// <script> This line added because my IDE has problems detecting JS ~ 0330 ~ duz

var needToShowChangeLog = false;
var upgradeFromVersion = null;

var THREAD_ICON_COUNT = 2;

//var expireMinAge = 7;  // how many days old must a thread entry be before it's deleted?

// WARNING WARNING WARNING WARNING
// Changing the following value, or any of the code that enforces the delay,
// you may get banned from the forums. This delay is here at radium's command!
var minMyThreadRefreshInterval = 60;

var initialDocShellPrepared = false;
var thisWindowPageTimers = new Array();

//////////////////////////////////////////////

var persistObject = null;

function GetUserProfileDirectory(fn) {
	const DIR_SERVICE = new Components.Constructor("@mozilla.org/file/directory_service;1", "nsIProperties");
	var path;
	try {
		path = (new DIR_SERVICE()).get("ProfD", Components.interfaces.nsIFile).path;
	} catch (e) {
	}
	if (path) {
		if (fn) {
			if (path.search(/\\/) != -1) {
				path = path + "\\";
			} else {
				path = path + "/";
			}
			path = path + fn;
		}
		return path;
	} else {
		return null;
	}
}

function ReadFile(fn) {
	try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
		return null;
	}
	var file = Components.classes["@mozilla.org/file/local;1"]
	.createInstance(Components.interfaces.nsILocalFile);
	file.initWithPath(fn);
	if (file.exists() == false) {
		return "";
	}
	var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
	.createInstance(Components.interfaces.nsIFileInputStream);
	is.init(file, 0x01, 00004, null);
	var sis = Components.classes["@mozilla.org/scriptableinputstream;1"]
	.createInstance(Components.interfaces.nsIScriptableInputStream);
	sis.init(is);
	return sis.read( sis.available() );
}

function SaveFile(fn, fdata) {
	try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
		alert("The SALastRead failed to save settings because permission was denied.");
		return null;
	}
	var file = Components.classes["@mozilla.org/file/local;1"]
	.createInstance(Components.interfaces.nsILocalFile);
	file.initWithPath(fn);
	if ( file.exists() == false ) {
		file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420);
		alert("The SALastRead extension is initializing a new settings file. You should only see this once, after you first install the extension.");
	}
	var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
	.createInstance(Components.interfaces.nsIFileOutputStream);
	outputStream.init(file, 0x04 | 0x08 | 0x20, 420, 0);
	var result = outputStream.write( fdata, fdata.length );
	outputStream.close();
}

function StripSpaces(str) {
	while (str.substring(0,1) > '~' || str.substring(0,1) < '!') str = str.substring(1);
	while (str.substring(str.length-1, str.length) == ' ') str = str.substring(0, str.length-1);
	return str;
}

function GetCurrentLPDateTime() {
	var now = new Date();
	var day = "00" + now.getDate();
	var month = "00" + (now.getMonth()+1);
	var year = "00" + (now.getYear()+1900);
	var hour = "00" + now.getHours();
	var minute = "00" + now.getMinutes();
	day = day.substring(day.length-2,day.length);
	month = month.substring(month.length-2,month.length);
	year = year.substring(year.length-4,year.length);
	hour = hour.substring(hour.length-2,hour.length);
	minute = minute.substring(minute.length-2,minute.length);
	return year + month + day + hour + minute;
}

function ConvertLPDateTimeToNum(lpdate, lptime) {
	// Jun 05, 2006    14:46
	// 012345678901    01234
	var monthstr = lpdate.substring(0,3);  // "Jun"
	var day = lpdate.substring(4,6);       // "05"
	var year = lpdate.substring(8,12);     // "2006"
	var hour = lptime.substring(0,2);      // "14"
	var minute = lptime.substring(3,6);    // "46"
	var month = "00";
	if (monthstr == "Jan") month = "01";
	if (monthstr == "Feb") month = "02";
	if (monthstr == "Mar") month = "03";
	if (monthstr == "Apr") month = "04";
	if (monthstr == "May") month = "05";
	if (monthstr == "Jun") month = "06";
	if (monthstr == "Jul") month = "07";
	if (monthstr == "Aug") month = "08";
	if (monthstr == "Sep") month = "09";
	if (monthstr == "Oct") month = "10";
	if (monthstr == "Nov") month = "11";
	if (monthstr == "Dec") month = "12";
	return year + month + day + hour + minute;
}

function SALRCachedThreadEntry(threadid) {
	this._xmlnode = selectSingleNode(persistObject.xmlDoc, persistObject.xmlDoc, "/salastread/thread[@id='"+threadid+"']");
	if ( !this._xmlnode ) {
		var newel = persistObject.xmlDoc.createElement("thread");
		newel.setAttribute("id", threadid);
		newel.setAttribute("lastpostdt", "0");
		newel.setAttribute("lastpostid", "0");
		this._needadd = true;
		//persistObject.xmlDoc.documentElement.insertBefore(newel, persistObject.xmlDoc.documentElement.firstChild);
		this._xmlnode = newel;
	}
	this._expireage = (new Date()).getTime();
}

SALRCachedThreadEntry.prototype = {
	_needadd: false,
	_xmlnode: null,
	_expireage: null,

	_frozen: false,
	_frozendt: false,
	_frozenid: false,
	_lastpostdt: null,
	_lastpostid: null,

	IsAged: function() {
		var now = (new Date()).getTime();
		return ( now >= this._expireage );
	},

	_setDelay: function() {
		this._expireage = (new Date()).getTime() + 5000;
	},

	renewDelay: function() {
		if ( this._frozen && !this.IsAged() ) {
			this._setDelay();
		}
	},

	getBypassAttribute: function(name) {
		return this._xmlnode.getAttribute(name);
	},

	getAttribute: function(name) {
		if ( this._frozen && name=="lastpostdt" && !this.IsAged() ) {
			return this._lastpostdt;
		}
		else if ( this._frozen && name=="lastpostid" && !this.IsAged() ) {
			return this._lastpostid;
		}
		else {
			return this._xmlnode.getAttribute(name);
		}
	},

	removeAttribute: function(name) {
		return this._xmlnode.removeAttribute(name);
	},

	setAttribute: function(name, value) {
		if ( !this._frozen ) {
			if ( name=="lastpostdt" && !this._frozendt ) {
				this._lastpostdt = this._xmlnode.getAttribute(name);
				this._frozendt = true;
			}
			if ( name=="lastpostid" && !this._frozenid ) {
				this._lastpostid = this._xmlnode.getAttribute(name);
				this._frozenid = true;
			}
			if ( this._frozendt && this._frozenid ) {
				this._frozen = true;
				this._setDelay();
				if (this._needadd) {
					persistObject.xmlDoc.documentElement.insertBefore(this._xmlnode, persistObject.xmlDoc.documentElement.firstChild);
					persistObject.xmlDoc.documentElement.insertBefore(persistObject.xmlDoc.createTextNode("\n"), persistObject.xmlDoc.documentElement.firstChild);
					this._needadd = false;
				}
			}
		}
		return this._xmlnode.setAttribute(name, value);
	},
};

//var cachedThreadEntryList = new Array();

function invalidateAgedCachedEntries() {
	var newList = new Array();
	for (var i=0; i<persistObject._cachedThreadEntryList.length; i++) {
		var thisEntry = persistObject._cachedThreadEntryList[i];
		if ( !thisEntry.IsAged() ) {
			newList.push(thisEntry);
		}
	}
	persistObject._cachedThreadEntryList = newList;
}

var cachedThreadEntry = null;

function slurpIntoThreadCache(threadid) {
	var needRead = false;
	if ( cachedThreadEntry ) {
		if ( cachedThreadEntry.getAttribute("id") != threadid ) {
			needRead = true;
		}
	} else {
		needRead = true;
	}
	if (needRead) {
		invalidateAgedCachedEntries();
		cachedThreadEntry = null;
		for (var i=0; i<persistObject._cachedThreadEntryList.length; i++) {
			if ( persistObject._cachedThreadEntryList[i].getAttribute("id")==threadid ) {
				cachedThreadEntry = persistObject._cachedThreadEntryList[i];
				cachedThreadEntry.setAttribute("lastviewdt", SALR_GetCurrentDT());
				return;
			}
		}
		if (!cachedThreadEntry) {
			cachedThreadEntry = new SALRCachedThreadEntry(threadid);
			persistObject._cachedThreadEntryList.push(cachedThreadEntry);
			//cachedThreadEntry = selectSingleNode(persistObject.xmlDoc, persistObject.xmlDoc, "/salastread/thread[@id='"+threadid+"']");
		}
	}
	cachedThreadEntry.setAttribute("lastviewdt", SALR_GetCurrentDT());
}

function SALR_GetCurrentDT() {
	return GetCurrentLPDateTime();
}

function invalidateThreadCache() {
	cachedThreadEntry = null;
}

function IsThreadIgnored(threadid) {
	slurpIntoThreadCache(threadid);
	if (cachedThreadEntry) {
		return (cachedThreadEntry.getAttribute("ignore")=="1");
	} else {
		return false;
	}
}

function IsLPDateTimeNew(bypassdelay, lpdtvalue, threadid, postid) {
	slurpIntoThreadCache(threadid);
	var lpidok = false;
	if (cachedThreadEntry) {
		if (bypassdelay) {
			lpidok = cachedThreadEntry.getBypassAttribute("lastpostid")>0;
		} else {
			lpidok = cachedThreadEntry.getAttribute("lastpostid")>0;
		}
	}
	//if (cachedThreadEntry && cachedThreadEntry.getAttribute("lastpostid")>0) {
	if (lpidok) {
		var lastdtval;
		var lpid;
		if ( bypassdelay ) {
			lastdtval = cachedThreadEntry.getBypassAttribute("lastpostdt");
			lpid = cachedThreadEntry.getBypassAttribute("lastpostid");
		} else {
			cachedThreadEntry.renewDelay();
			lastdtval = cachedThreadEntry.getAttribute("lastpostdt");
			lpid = cachedThreadEntry.getAttribute("lastpostid");
		}
		if ( lastdtval < lpdtvalue ) {
			return "readwithnew";
		} else {
			if ( !postid || postid <= lpid ) {
				return false;
			} else {
				return "readwithnew";
			}
		}
	} else {
		return "unread";
	}
}

function GetLastPostID(threadid) {
	slurpIntoThreadCache(threadid);
	return cachedThreadEntry.getAttribute("lastpostid");
}

function GetPostedInThread(threadid) {
	slurpIntoThreadCache(threadid);
	return cachedThreadEntry.getAttribute("posted");
}

function UpdateLPDateTime(updateTo, threadid, lastpostid) {
	slurpIntoThreadCache(threadid);
	if ( cachedThreadEntry ) {
		cachedThreadEntry.setAttribute("lastpostdt", updateTo);
		cachedThreadEntry.setAttribute("lastpostid", lastpostid);
	} else {
		alert("SALastRead: should never get here");
		var newel = persistObject.xmlDoc.createElement("thread");
		newel.setAttribute("id", threadid);
		newel.setAttribute("lastpostdt", updateTo);
		newel.setAttribute("lastpostid", lastpostid);
		persistObject.xmlDoc.documentElement.insertBefore(newel, persistObject.xmlDoc.documentElement.firstChild);
	}
	//persistObject.SaveXML();
	var threaddetails = new Array();
	threaddetails['id'] = threadid;
	threaddetails['lastpostdt'] = updateTo;
	threaddetails['lastpostid'] = lastpostid;
	persistObject.SavePostDataSQL(threaddetails);
}

function SALRHexToNumber(hex) {
	var res = 0;
	for (var i=0; i<hex.length; i++) {
		res = res * 16;
		switch (hex[i]) {
			case "0": res += 0; break;
			case "1": res += 1; break;
			case "2": res += 2; break;
			case "3": res += 3; break;
			case "4": res += 4; break;
			case "5": res += 5; break;
			case "6": res += 6; break;
			case "7": res += 7; break;
			case "8": res += 8; break;
			case "9": res += 9; break;
			case "a": case "A": res += 10; break;
			case "b": case "B": res += 11; break;
			case "c": case "C": res += 12; break;
			case "d": case "D": res += 13; break;
			case "e": case "E": res += 14; break;
			case "f": case "F": res += 15; break;
		}
	}
	return res;
}

function SALR_MakeShowThreadCSS() {
	var csstxt = "";
	csstxt += "table.salastread_seenpost.salastread_odd tr { background-color: "+persistObject.color_seenPostDark+" !important; }\n\n";
	csstxt += "table.salastread_seenpost.salastread_even tr { background-color: "+persistObject.color_seenPostLight+" !important; }\n\n";
	//csstxt += "table.salastread_unseenpost.salastread_odd tr { background-color: "+persistObject.color_unseenPostDark+" !important; }\n\n";
	//csstxt += "table.salastread_unseenpost.salastread_even tr { background-color: "+persistObject.color_unseenPostLight+" !important; }\n\n";
	if ( persistObject.toggle_hideTitle ) {
		csstxt += "dd.title * { display: none; }\n\n";
	} else if ( persistObject.toggle_resizeCustomTitleText ) {
		csstxt += "dd.title * { font-size: 8pt; }\n\n";
	}

	if ( persistObject.toggle_hideSignature)
	{
		//So yeah firefox comes up with a pretty unique way of
		//interpretting SA's invalid HTML......
		csstxt += ".signature + p + div { display: none; }\n\n"
	}

	// HEREHERE
	return csstxt;
}

function SALR_MakeForumDisplayCSS() {
	var sub = function(cls, isdark, basecolor, highlightcolor) {
		var res = "";
		if (isdark) {
			res += "tr."+cls+" td.icon,";
			res += "tr."+cls+" td.author,";
			res += "tr."+cls+" td.views,";
			res += "tr."+cls+" td.lastpost";
		} else {
			res += "tr."+cls+" td.title,";
			res += "tr."+cls+" td.replies,";
			res += "tr."+cls+" td.rating";
		}
		res += " { background-repeat: repeat-x !important; background-color: "+basecolor + " !important";
		if (highlightcolor && !persistObject.toggle_disableGradients) {
			res += "; background-image: url(x-salr-gradientpng:" +
			SALRHexToNumber(highlightcolor.substring(1,3)) + "," +
			SALRHexToNumber(highlightcolor.substring(3,5)) + "," +
			SALRHexToNumber(highlightcolor.substring(5,7)) + "," +
			"33) !important";
		}
		res += "; }\n\n";

		res += "tr.salastread_postedinthread td.replies { background-repeat: repeat-x !important; background-color: "+
		persistObject.color_postedInThreadRe + " !important";
		if (persistObject.color_postedInThreadReHighlight && !persistObject.toggle_disableGradients) {
			var highlightcolor = persistObject.color_postedInThreadReHighlight;
			res += "; background-image: url(x-salr-gradientpng:" +
			SALRHexToNumber(highlightcolor.substring(1,3)) + "," +
			SALRHexToNumber(highlightcolor.substring(3,5)) + "," +
			SALRHexToNumber(highlightcolor.substring(5,7)) + "," +
			"33) !important";
		}
		res += "; }\n\n";

		return res;
	};

	var csstext = "";
	csstext += sub("salastread_readthread", true, persistObject.color_readDark, persistObject.color_readDarkHighlight);
	csstext += sub("salastread_readthread", false, persistObject.color_readLight, persistObject.color_readLightHighlight);
	csstext += sub("salastread_readwithnewthread", true, persistObject.color_readWithNewDark, persistObject.color_readWithNewDarkHighlight);
	csstext += sub("salastread_readwithnewthread", false, persistObject.color_readWithNewLight, persistObject.color_readWithNewLightHighlight);
	//csstext += sub("salastread_unreadthread", true, persistObject.color_unreadDark, persistObject.color_unreadDarkHighlight);
	//csstext += sub("salastread_unreadthread", false, persistObject.color_unreadLight, persistObject.color_unreadLightHighlight);
	csstext += "td.replies { white-space: nowrap; }\n\n";
	csstext += ".salastread_newreplycount { font-weight: normal !important; }\n\n";

	return csstext;
}

function changeBGColorsFromTo(doc, context, xpathbase, bgfrom, bgto, bgtohighlight) {
	var xarray = selectNodes(doc, context, xpathbase+"[@bgcolor='"+bgfrom+"']");
	for (var x=0; x<xarray.length; x++) {
		xarray[x].style.backgroundColor = bgto;
		if ( bgtohighlight && !persistObject.toggle_disableGradients ) {
			xarray[x].style.backgroundRepeat = "repeat-x";
			xarray[x].style.backgroundImage = "url(x-salr-gradientpng:"+
			SALRHexToNumber( bgtohighlight.substring(1,3) ) + "," +
			SALRHexToNumber( bgtohighlight.substring(3,5) ) + "," +
			SALRHexToNumber( bgtohighlight.substring(5,7) ) + "," +
			"33)";
		}
	}
	return xarray;
}

//function setSeenPostFYADColors(doc, context, xpathbase) {
//   if ( persistObject.toggle_dontHighlightPosts ) { return; }
//   changeBGColorsFromTo(doc, context, xpathbase, "#ffccff", persistObject.color_seenPostLightFYAD);
//   changeBGColorsFromTo(doc, context, xpathbase, "#ffcccc", persistObject.color_seenPostDarkFYAD);
//}

function setSeenPostColors(doc, context, xpathbase) {
	if ( persistObject.toggle_dontHighlightPosts ) { return; }
	//changeBGColorsFromTo(doc, context, xpathbase, "#f1f1f1", persistObject.color_seenPostLight);
	//changeBGColorsFromTo(doc, context, xpathbase, "#dfdfdf", persistObject.color_seenPostDark);
	context.className += " salastread_seenpost";
	context.nextSibling.className += " salastread_seenpostbar";
}

//function setUnseenPostFYADColors(doc, context, xpathbase) {
//   if ( persistObject.toggle_dontHighlightPosts ) { return; }
//   changeBGColorsFromTo(doc, context, xpathbase, "#ffccff", persistObject.color_unseenPostLightFYAD);
//   changeBGColorsFromTo(doc, context, xpathbase, "#ffcccc", persistObject.color_unseenPostDarkFYAD);
//}

function setUnseenPostColors(doc, context, xpathbase) {
	if ( persistObject.toggle_dontHighlightPosts ) { return; }
	//changeBGColorsFromTo(doc, context, xpathbase, "#f1f1f1", persistObject.color_unseenPostLight);
	//changeBGColorsFromTo(doc, context, xpathbase, "#dfdfdf", persistObject.color_unseenPostDark);
	context.className += " salastread_unseenpost";
	context.nextSibling.className += " salastread_unseenpostbar";
}

function setReadColors(doc, context, xpathbase) {
	if ( persistObject.toggle_dontHighlightThreads ) { return; }
	var res = new Array(2);
	var r0 = changeBGColorsFromTo(doc, context, xpathbase, "#ffccff",
	persistObject.color_readLight, persistObject.color_readLightHighlight);
	var r1 = changeBGColorsFromTo(doc, context, xpathbase, "#ffcccc",
	persistObject.color_readDark, persistObject.color_readDarkHighlight);
	res[0] = changeBGColorsFromTo(doc, context, xpathbase, "#f4f4f4",
	persistObject.color_readLight, persistObject.color_readLightHighlight);
	res[1] = changeBGColorsFromTo(doc, context, xpathbase, "#e8e8e8",
	persistObject.color_readDark, persistObject.color_readDarkHighlight);
	for (var x=0; x<r0.length; x++) { res[0].push(r0[x]); }
	for (var y=0; y<r1.length; y++) { res[1].push(r1[y]); }
	return res;
}

function setReadWithNewColors(doc, context, xpathbase) {
	if ( persistObject.toggle_dontHighlightThreads ) { return; }
	var res = new Array(2);
	var r0 = changeBGColorsFromTo(doc, context, xpathbase, "#ffccff",
	persistObject.color_readWithNewLight, persistObject.color_readWithNewLightHighlight);
	var r1 = changeBGColorsFromTo(doc, context, xpathbase, "#ffcccc",
	persistObject.color_readWithNewDark, persistObject.color_readWithNewDarkHighlight);
	res[0] = changeBGColorsFromTo(doc, context, xpathbase, "#f4f4f4",
	persistObject.color_readWithNewLight, persistObject.color_readWithNewLightHighlight);
	res[1] = changeBGColorsFromTo(doc, context, xpathbase, "#e8e8e8",
	persistObject.color_readWithNewDark, persistObject.color_readWithNewDarkHighlight);
	for (var x=0; x<r0.length; x++) { res[0].push(r0[x]); }
	for (var y=0; y<r1.length; y++) { res[1].push(r1[y]); }
	return res;
}

function setUnreadColors(doc, context, xpathbase) {
	if ( persistObject.toggle_dontHighlightThreads ) { return; }
	var res = new Array(2);
	res[0] = changeBGColorsFromTo(doc, context, xpathbase, "#f4f4f4",
	persistObject.color_unreadLight, persistObject.color_unreadLightHighlight);
	res[1] = changeBGColorsFromTo(doc, context, xpathbase, "#e8e8e8",
	persistObject.color_unreadDark, persistObject.color_unreadDarkHighlight);
	return res;
}

function setUnreadFYADColors(doc, context, xpathbase) {
	if ( persistObject.toggle_dontHighlightThreads ) { return; }
	var res = new Array(2);
	res[0] = changeBGColorsFromTo(doc, context, xpathbase, "#ffccff",
	persistObject.color_unreadLightFYAD, persistObject.color_unreadLightFYADHighlight);
	res[1] = changeBGColorsFromTo(doc, context, xpathbase, "#ffcccc",
	persistObject.color_unreadDarkFYAD, persistObject.color_unreadDarkFYADHighlight);
	return res;
}

function resetUnreadColors(unvisitDecolors) {
	if ( persistObject.toggle_dontHighlightThreads ) { return; }
	for (var i=0; i<unvisitDecolors[0].length; i++) {
		unvisitDecolors[0][i].style.backgroundColor = persistObject.color_unreadLight;
		unvisitDecolors[0][i].style.backgroundImage = "";
	}
	for (var j=0; j<unvisitDecolors[1].length; j++) {
		unvisitDecolors[1][j].style.backgroundColor = persistObject.color_unreadDark;
		unvisitDecolors[1][j].style.backgroundImage = "";
	}
}

function SAmenuitemCommand2(event,el,etype) {
	var target = "none";
	if ( etype=="command" ) {
		target = "current";
	}
	if ( etype=="click" ) {
		if ( event.button == 2 || event.button == 1 ) {
			target = "newtab";
		}
	}

	if (target != "none") {
		SAmenuitemGoto(event,"http://forums.somethingawful.com/forumdisplay.php?s=&forumid="+el.getAttribute("forumnum"),target);
	}
}

function SAmenuitemCommandGoToLastPost(event, el, etype, threadid) {
	slurpIntoThreadCache(threadid);
	if (cachedThreadEntry) {
		var postid = cachedThreadEntry.getAttribute("lastpostid");
		SAmenuitemCommandURL2(event, "http://forums.somethingawful.com/showthread.php?s=&postid="+postid+"#post"+postid, etype);
	}
}

function SAmenuitemCommandURL2(event,el,etype) {
	var target = "none";
	if ( etype=="command" ) {
		target = "current";
	}
	if ( etype=="click" ) {
		if ( event.button == 2 || event.button == 1 ) {
			target = "newtab";
		}
	}

	var targeturl = "";
	if ( typeof(el) == "string" ) {
		targeturl = el;
	} else {
		targeturl = el.getAttribute("targeturl");
	}

	if (target != "none") {
		SAmenuitemGoto(event,targeturl,target);
	}
}

function SAmenuitemGoto(event,url,target) {
	if (target=="newtab") {
		getBrowser().addTab(url);
	}
	else if (target=="current") {
		loadURI(url);
	}
}

function grabForumList(e, selectnode) {
	var doc = e.originalTarget;
	var optionlist = selectNodes(doc, selectnode, "OPTION");
	var oDomParser = new DOMParser();
	var forumsDoc = oDomParser.parseFromString("<?xml version=\"1.0\"?>\n<forumlist></forumlist>", "text/xml");
	var targetEl = forumsDoc.documentElement;
	var oldForumXml = persistObject.forumListXml;
	for (var i=0; i<optionlist.length; i++) {
		var thisopt = optionlist[i];
		var thisopttext = thisopt.firstChild.nodeValue;
		if ( thisopttext.substring(0,2)=="--" && thisopt.getAttribute("value")!="-1" ) {
			var fel = forumsDoc.createElement("forum");
			var myid = thisopt.getAttribute("value");
			fel.setAttribute("id", myid);

			// Carry over sticky attributes
			if ( oldForumXml ) {
				var oldEl = selectSingleNode(oldForumXml, oldForumXml, "//forum[@id='"+myid+"']");
				if (oldEl) {
					if ( oldEl.hasAttribute("mods") ) {
						fel.setAttribute("mods", oldEl.getAttribute("mods"));
					}
					if ( oldEl.hasAttribute("modnames") ) {
						fel.setAttribute("modnames", oldEl.getAttribute("modnames"));
					}
				}
			}

			var catname = "sub";
			var xtext = thisopttext.substring(2);
			while ( xtext.substring(0,2)=="--" ) {
				catname += "-sub";
				xtext = xtext.substring(2);
			}
			xtext = xtext.substring(1);
			fel.setAttribute("name", xtext);
			fel.setAttribute("cat", catname);

			//         if (thisopttext.substring(0,5)=="---- " && thisopt.getAttribute("value")!="-1" ) {
			//            fel.setAttribute("name", "     " + thisopttext.substring(5));
			//            fel.setAttribute("cat","sub-sub");
			//         } else {
			//            fel.setAttribute("name", thisopttext.substring(3));
			//            fel.setAttribute("cat","sub");
			//         }
			targetEl.appendChild(fel);
			targetEl.insertBefore(forumsDoc.createTextNode("\n"), fel);
		} else if (thisopt.getAttribute("value")!="-1" ) {
			var fel;
			if ( thisopt.getAttribute("value").match(/\D/) ) {
				fel = forumsDoc.createElement("util");
			} else {
				fel = forumsDoc.createElement("cat");
				targetEl = fel;
			}
			if(thisopttext.substring(0,1)  == " ") {
				fel.setAttribute("name", thisopttext.substring(1));
			} else {
				fel.setAttribute("name", thisopttext);
			}
			fel.setAttribute("id", thisopt.getAttribute("value"));
			forumsDoc.documentElement.appendChild(fel);
			forumsDoc.documentElement.insertBefore(forumsDoc.createTextNode("\n"), fel);
		}
	}
	persistObject.forumListXml = forumsDoc;
	if ( persistObject.toggle_showSAForumMenu ) {
		buildSAForumMenu();
	}
}

function populateForumMenuFrom(nested_menus,target,src,pinnedForumNumbers,pinnedForumElements) {
	var wasutil = 0;
	for (var i=0; i<src.childNodes.length; i++) {
		var thisforum = src.childNodes[i];
		if (thisforum.nodeName=="util") {
			wasutil = 1;
		}
		else if (wasutil && thisforum.nodeType == 1) {
			if (nested_menus) {
				target.appendChild(document.createElement("menuseparator"));
			}
			wasutil = 0;
		}
		if (thisforum.nodeName=="cat") {
			if (!nested_menus) {
				target.appendChild(document.createElement("menuseparator"));
				populateForumMenuFrom(nested_menus,target,thisforum,pinnedForumNumbers,pinnedForumElements);
			} else {
				var submenu = document.createElement("menu");
				submenu.setAttribute("label", thisforum.getAttribute("name"));
				var submenupopup = document.createElement("menupopup");
				if ( persistObject.toggle_useSAForumMenuBackground ) {
					submenupopup.setAttribute("class", "lastread_menu");
				}
				submenu.appendChild(submenupopup);
				populateForumMenuFrom(nested_menus,submenupopup,thisforum,pinnedForumNumbers,pinnedForumElements);
				target.appendChild(submenu);
			}
		}
		else if (thisforum.nodeName=="forum"||thisforum.nodeName=="util") {
			var menuel = document.createElement("menuitem");
			menuel.setAttribute("label", thisforum.getAttribute("name"));
			menuel.setAttribute("forumnum", thisforum.getAttribute("id"));
			menuel.setAttribute("onclick", "SAmenuitemCommand2(event,this,'click');");
			menuel.setAttribute("oncommand", "SAmenuitemCommand2(event,this,'command');");
			if (thisforum.getAttribute("cat") && thisforum.getAttribute("cat").substring(0,3)=="sub") {
				menuel.setAttribute("class", "lastread_menu_"+ thisforum.getAttribute("cat"));
			}
			/*
			if (thisforum.getAttribute("cat")=="sub") {
			menuel.setAttribute("class", "lastread_menu_sub");
			}
			else if (thisforum.getAttribute("cat")=="sub-sub") {
			menuel.setAttribute("class", "lastread_menu_sub_sub");
			}
			*/
			//TODO: access keys
			target.appendChild(menuel);
			if (nested_menus) {
				var thisforumnum = thisforum.getAttribute("id");
				for (var j=0; j<pinnedForumNumbers.length; j++) {
					if (pinnedForumNumbers[j]==thisforumnum) {
						pinnedForumElements[j] = thisforum;
					}
				}
			}
		}
	}
}

function SALR_DEBUG_ViewXMLData() {
	var threads = selectNodes(persistObject.xmlDoc, persistObject.xmlDoc, "/salastread/thread");
	var nName = persistObject.xmlDoc.documentElement.nodeName;
	var nmsg;
	if (nName=="salastread") {
		nmsg = "This is correct.";
	} else {
		nmsg = "THIS IS NOT CORRECT.";
	}
	var tclen = persistObject._cachedThreadEntryList.length;
	alert("There are "+ threads.length + " threads stored.\nThe root is named "+nName+". "+nmsg+"\nThere are "+tclen+" entries in the CTEL.");
}

function SALR_DEBUG_ResetXMLData() {
	if ( confirm("Are you sure you want to reset the salastread.xml data?\nThis will lose all viewed threads, posted threads, and starred threads.") ) {
		persistObject._cachedThreadEntryList = new Array();

		persistObject.InitializeEmptySALRXML();
		persistObject.SaveXML();
		alert("salastread.xml has been reset.");
	} else {
		alert("Operation cancelled.");
	}
}

function SALR_InsertDebugMenuEntries(targetpopup) {
	var AME = function(lab, fnc) {
		var xfoo = document.createElement("menuitem");
		xfoo.setAttribute("label", lab);
		xfoo.addEventListener("command", fnc, false);
		targetpopup.appendChild(xfoo);
	};

	AME("View salastread.xml Data", function() { SALR_DEBUG_ViewXMLData(); });
	AME("Reset salastread.xml Data", function() { SALR_DEBUG_ResetXMLData(); });
	//AME("TEST FTP UPLOAD GOOD", function() { SALR_DEBUG_TestFTPUpload("s"); });
	//AME("TEST FTP UPLOAD BAD", function() { SALR_DEBUG_TestFTPUpload("b"); });
	//AME("TEST FTP DOWNLOAD GOOD", function() { SALR_DEBUG_TestFTPDownload("s"); });
	//AME("TEST FTP DOWNLOAD BAD", function() { SALR_DEBUG_TestFTPDownload("b"); });
	AME("Syncxx", function() { persistObject.FirefoxShuttingDown(); });
	AME("Normal Sync Call", function() { SALR_SyncTick(false,false); });
	AME("Force Sync Call", function() { SALR_SyncTick(true,false); });
	AME("TRACE CONFIG", function() { SALR_SyncTick(true,true); });
}

var SALR_DEBUG_pendingUpload = null;
var SALR_DEBUG_pendingDownload = null;

function SALR_DEBUG_TestFTPDownload(xx) {
	var url = "ftp://admin:"+ "x" +"@evercrest.com/test.txt";
	var localfile = "c:\\documents and settings\\tim fries\\testin.txt"
	alert("before download");
	SALR_DEBUG_pendingDownload = new SALR_FTPTransferObject();
	SALR_DEBUG_pendingDownload.getFile(url, localfile, SALR_DEBUG_TestFTPDownloadDone);
}

function SALR_DEBUG_TestFTPDownloadDone(status) {
	alert("status = "+status);
	SALR_DEBUG_pendingDownload = null;
}

function SALR_DEBUG_TestFTPUpload(xx) {
	var url = "ftp://admin:"+ "x" +"@evercrest.com/test.txt";
	var localfile = "c:\\documents and settings\\tim fries\\test.txt"

	alert("before upload");
	SALR_DEBUG_pendingUpload = new SALR_FTPTransferObject();
	SALR_DEBUG_pendingUpload.sendFile(url, localfile, SALR_DEBUG_TestFTPUploadDone);
}
function SALR_DEBUG_TestFTPUploadDone(result) {
	if (result==0)
	alert("upload succeeded");
	else
	alert("upload failed");
	SALR_DEBUG_pendingUpload = null;
}

function buildSAForumMenu() {
	try {
		if ( persistObject.toggle_hideOtherSAMenus ) {
			var mmb = document.getElementById("main-menubar");
			for (var x=0; x<mmb.childNodes.length; x++) {
				var thischild = mmb.childNodes[x];
				if (thischild.nodeName=="menu") {
					if ( (thischild.getAttribute("label")=="SA" || thischild.label=="SA" || thischild.id=="menu-sa") &&
					thischild.id!="menu_SAforums") {
						mmb.removeChild(thischild);
						x--;
					}
				}
			}
		}
		var menupopup = document.getElementById("menupopup_SAforums");
		if (menupopup==null) {
			var iBefore = document.getElementById("bookmarks-menu");
			if (iBefore) {
				iBefore = iBefore.nextSibling;
			}
			if (!iBefore) {
				iBefore = document.getElementById("main-menubar").lastChild;
			}
			var menuel = document.createElement("menu");
			menuel.id = "menu_SAforums";
			menuel.setAttribute("label", "SA");
			menuel.setAttribute("accesskey","A");
			menuel.style.display = "none";
			menupopup = document.createElement("menupopup");
			menupopup.id = "menupopup_SAforums";
			menupopup.className = "lastread_menu";
			menuel.appendChild(menupopup);
			document.getElementById("main-menubar").insertBefore(menuel, iBefore);
			menupopup.addEventListener("popupshowing", SALR_SAMenuShowing, false);
		}
		if ( persistObject.toggle_useSAForumMenuBackground ) {
			menupopup.className = "lastread_menu";
		} else {
			menupopup.className = "";
		}
		while (menupopup.firstChild) {
			menupopup.removeChild(menupopup.firstChild);
		}
		var forumsDoc = persistObject.forumListXml;
		var nested_menus = persistObject.toggle_nestSAForumMenu;
		var menuel = document.createElement("menuitem");
		var pinnedForumNumbers = new Array();
		var pinnedForumElements = new Array();
		if (nested_menus && persistObject.string_menuPinnedForums) {
			pinnedForumNumbers = persistObject.string_menuPinnedForums.split(",");
		}
		menuel.setAttribute("label","Something Awful");
		menuel.setAttribute("image", "chrome://salastread/content/sa.png");
		menuel.setAttribute("onclick", "SAmenuitemCommandURL2(event,'http://www.somethingawful.com','click');");
		menuel.setAttribute("oncommand", "SAmenuitemCommandURL2(event,'http://www.somethingawful.com','command');");
		menuel.setAttribute("class","menuitem-iconic lastread_menu_frontpage");
		menupopup.appendChild(menuel);
		menupopup.appendChild(document.createElement("menuseparator"));

		var lmenuel = document.createElement("menuitem");
		lmenuel.setAttribute("label","Configure SALastRead...");
		//lmenuel.setAttribute("onclick", "runConfig('click');");
		lmenuel.setAttribute("oncommand", "SALR_runConfig('command');");
		menupopup.appendChild(lmenuel);

		if ( persistObject.IsDebugEnabled() ) {
			var dmenuel = document.createElement("menu");
			dmenuel.setAttribute("label","SALR Debug");
			var dmenupopup = document.createElement("menupopup");

			SALR_InsertDebugMenuEntries(dmenupopup);

			dmenuel.appendChild(dmenupopup);
			menupopup.appendChild(dmenuel);
		}

		menupopup.appendChild(document.createElement("menuseparator"));

		populateForumMenuFrom(nested_menus,menupopup,forumsDoc.documentElement,pinnedForumNumbers,pinnedForumElements);

		if (nested_menus && pinnedForumElements.length > 0) {
			menupopup.appendChild(document.createElement("menuseparator"));
			for (var j=0; j<pinnedForumElements.length || j<pinnedForumNumbers.length; j++) {
				if (pinnedForumElements[j]) {
					var thisforum = pinnedForumElements[j];
					var menuel = document.createElement("menuitem");
					var forumname = thisforum.getAttribute("name");
					while (forumname.substring(0,1)==" ") {
						forumname = forumname.substring(1);
					}
					menuel.setAttribute("label", forumname);
					menuel.setAttribute("forumnum", thisforum.getAttribute("id"));
					menuel.setAttribute("onclick", "SAmenuitemCommand2(event,this,'click');");
					menuel.setAttribute("oncommand", "SAmenuitemCommand2(event,this,'command');");
					menuel.setAttribute("class", "lastread_menu_sub");
					menupopup.appendChild(menuel);
				}
				else if (pinnedForumNumbers[j]=="sep") {
					menupopup.appendChild( document.createElement("menuseparator") );
				}
				else if (typeof(pinnedForumNumbers[j])=="string" && pinnedForumNumbers[j].substring(0,3)=="URL") {
					var umatch = pinnedForumNumbers[j].match(/^URL\[(.*?)\]\[(.*?)\]$/);
					if (umatch) {
						var menuel = document.createElement("menuitem");
						menuel.setAttribute("label", persistObject.UnescapeMenuURL(umatch[1]));
						menuel.setAttribute("targeturl", persistObject.UnescapeMenuURL(umatch[2]));
						menuel.setAttribute("onclick", "SAmenuitemCommandURL2(event,this,'click');");
						menuel.setAttribute("oncommand", "SAmenuitemCommandURL2(event,this,'command');");
						menuel.setAttribute("class", "lastread_menu_sub");
						menupopup.appendChild(menuel);
					}
				}
				else if (pinnedForumNumbers[j]=="starred") {
					var menuel = document.createElement("menu");
					menuel.setAttribute("label", "Starred Threads");
					menuel.setAttribute("image", "chrome://salastread/content/star.png");
					menuel.setAttribute("class", "menu-iconic lastread_menu_starred");

					var subpopup = document.createElement("menupopup");
					subpopup.id = "salr_starredthreadmenupopup";

					menuel.appendChild(subpopup);
					menupopup.appendChild(menuel);

					subpopup.setAttribute("onpopupshowing", "SALR_StarredThreadMenuShowing();");
				}
			}
			if ( persistObject.toggle_showMenuPinHelper ) {
				var ms = document.createElement("menuseparator");
				ms.id = "salr_pinhelper_sep";
				menupopup.appendChild(ms);
				var menuel = document.createElement("menuitem");
				menuel.id = "salr_pinhelper_item";
				menuel.setAttribute("label", "Learn how to pin forums to this menu...");
				menuel.setAttribute("image", "chrome://salastread/content/eng101-16x16.png");
				menuel.setAttribute("oncommand", "SALR_LaunchPinHelper();");
				menuel.setAttribute("class", "menuitem-iconic lastread_menu_sub");
				menupopup.appendChild(menuel);
			}
		}

		document.getElementById("menu_SAforums").style.display = "-moz-box";
	} catch(exc) { alert("menuerr: "+exc); }
}

function SALR_StarredThreadMenuShowing() {
	//alert("here");
	var menupopup = document.getElementById("salr_starredthreadmenupopup");
	while (menupopup.firstChild != null) {
		menupopup.removeChild(menupopup.firstChild);
	}

	var starredThreads = selectNodes(persistObject.xmlDoc, persistObject.xmlDoc, "/salastread/thread[@star='1']");
	for (var i=0; i<starredThreads.length; i++) {
		var threadid = starredThreads[i].getAttribute("id");
		var threadtitle = typeof(starredThreads[i].getAttribute("title"))=='string' ? starredThreads[i].getAttribute("title") : "Unknown Thread Title ("+threadid+")";
		var menuel = document.createElement("menuitem");
		menuel.setAttribute("label", threadtitle);
		menuel.setAttribute("onclick", "SAmenuitemCommandGoToLastPost(event,this,'click',"+threadid+");");
		menuel.setAttribute("oncommand", "SAmenuitemCommandGoToLastPost(event,this,'command',"+threadid+");");
		menupopup.appendChild(menuel);
	}
}

function SALR_SAMenuShowing() {
	//alert("here - " + persistObject.toggle_showMenuPinHelper);
	if ( persistObject.toggle_showMenuPinHelper == false ) {
		var ms = document.getElementById("salr_pinhelper_sep");
		var mi = document.getElementById("salr_pinhelper_item");
		if ( ms != null ) {
			ms.parentNode.removeChild(ms);
		}
		if ( mi != null ) {
			mi.parentNode.removeChild(mi);
		}
	}
}

function SALR_LaunchPinHelper() {
	persistObject.toggle_showMenuPinHelper = false;
	persistObject.SavePrefs();
	SALR_runConfig("catMenuButton");
	alert("You may return to the menu settings at any time by choosing \"Configure SALastRead...\" from the SA menu, or by "+
	"clicking the \"Configure Last Read Extension\" link in the header of any forum page.");
}

/*
function grabForumList(e, selectnode) {
var doc = e.originalTarget;
var optionlist = selectNodes(doc, selectnode, "OPTION");
var oDomParser = new DOMParser();
var forumsDoc = oDomParser.parseFromString("<?xml version=\"1.0\"?>\n<forumlist></forumlist>", "text/xml");
for (var i=0; i<optionlist.length; i++) {
var thisopt = optionlist[i];
var thisopttext = thisopt.firstChild.nodeValue;
if ( thisopttext.substring(0,2)=="--" && thisopt.getAttribute("value")!="-1" ) {
var fel = forumsDoc.createElement("forum");
fel.setAttribute("id", thisopt.getAttribute("value"));
fel.setAttribute("name", thisopttext.substring(2));
forumsDoc.documentElement.appendChild(fel);
}
}
persistObject.forumListXml = forumsDoc;
if ( persistObject.toggle_showSAForumMenu ) {
buildSAForumMenu();
}
}

function buildSAForumMenu() {
var menupopup = document.getElementById("menupopup_SAforums");
while (menupopup.firstChild) {
menupopup.removeChild(menupopup.firstChild);
}
var forumsDoc = persistObject.forumListXml;
var forums = selectNodes(forumsDoc, forumsDoc.documentElement, "//forum");
for (var i=0; i<forums.length; i++) {
var thisforum = forums[i];
var menuel = document.createElement("menuitem");
menuel.setAttribute("label", thisforum.getAttribute("name"));
menuel.setAttribute("forumnum", thisforum.getAttribute("id"));
menuel.setAttribute("oncommand", "SAmenuitemCommand(this);"); // ", function(evt) { SAmenuitemCommand(evt); }, true );
menupopup.appendChild(menuel);
}
document.getElementById("menu_SAforums").style.display = "-moz-box";
}
*/

function handleSubscribedThreadTable(e, subTable) {
	var doc = e.originalTarget;
	//alert("here " + subTable.nodeName);
	var threadRows = selectNodes(doc, subTable, "TBODY/TR");  //[@id!='cat']");
	var firstMatch = 1;
	for (var i=0; i<threadRows.length; i++) {
		var thisRow = threadRows[i];
		if ( thisRow.id != "cat" ) {
			if (firstMatch) {
				firstMatch = 0;
			} else {
				//var threadlink = selectNodes(doc, thisRow, "TD/FONT/A[contains(@href,'showthread.php')]")[0];
				var threadlink = selectSingleNode(doc, thisRow, "TD/FONT/A[contains(@href,'showthread.php')]");
				//var lpdata = selectNodes(doc, thisRow, "TD/TABLE[@id='ltlink']/TBODY/TR/TD/FONT")[0];
				var lpdata = selectSingleNode(doc, thisRow, "TD/TABLE[@id='ltlink']/TBODY/TR/TD/FONT");
				if (threadlink && lpdata) {
					var lpdate = StripSpaces(lpdata.firstChild.nodeValue);
					var lptime = StripSpaces(lpdata.firstChild.nextSibling.firstChild.nodeValue);
					var threadid = threadlink.href.match(/threadid=(\d+)/)[1];
					var isFYAD = 0;
					var setClasses = 0;
					//var topictitletd = selectNodes(doc, thisRow, "TD[3]")[0];
					var topictitletd = selectSingleNode(doc, thisRow, "TD[3]");
					//var topicretd = selectNodes(doc, thisRow, "TD[5]")[0];
					var topicretd = selectSingleNode(doc, thisRow, "TD[5]");

					setUpThreadIcons(doc,thisRow,threadid,lpdate,lptime,isFYAD,setClasses,topictitletd,topicretd,0);

					var ulinknode = selectSingleNode(doc, thisRow, "TD[4]//A[contains(@href,'action=getinfo')]");
					if (ulinknode) {
						var uname = ulinknode.firstChild.nodeValue;
						uname = uname.replace(/[^A-Z0-9]/gi, "_");
						ulinknode.className += " somethingawfulforum_userlink_"+uname;
					}

					var llinknode = selectSingleNode(doc, thisRow, "TD[8]//A[contains(@href,'action=getinfo')]");
					if (llinknode) {
						var uname = llinknode.firstChild.firstChild.nodeValue;
						uname = uname.replace(/[^A-Z0-9]/gi, "_");
						llinknode.className += " somethingawfulforum_userlink_"+uname;
					}
				}
			}
		}
	}
}

function handleSubscriptions(e) {
	//alert("member2");
	var doc = e.originalTarget;
	//var subForm = selectNodes(doc, doc.body, "//FORM[@method='get'][contains(@action,'member2.php')]")[0];
	var subForm = selectSingleNode(doc, doc.body, "//FORM[@method='get'][contains(@action,'member2.php')]");
	if (subForm) {
		var subTable = subForm.parentNode;
		handleSubscribedThreadTable(e, subTable);
	}
}

function setUpThreadIcons(doc,thisel,threadid,lpdate,lptime,isFYAD,setClasses,topictitletd,topicretd,forumid) {
	var lpdtvalue = ConvertLPDateTimeToNum(StripSpaces(lpdate), StripSpaces(lptime));
	var isunread = IsLPDateTimeNew(true, lpdtvalue, threadid);
	var isignored = IsThreadIgnored(threadid);
	if (isignored) {
		thisel.style.display = "none";
	}
	thisel.lpdtvalue = lpdtvalue;
	thisel.className += " salastread_thread_" + threadid;
	if (isunread=="unread") {
		if ( setClasses ) {
			thisel.className += " salastread_unreadthread";
		}
		if ( isFYAD ) {
			setUnreadFYADColors(doc, thisel, "TD");
		} else {
			setUnreadColors(doc, thisel, "TD");
		}
	} else {
		var unvisitDecolors = null;
		var knownLastPostID = null;
		if (isunread=="readwithnew") {
			if ( setClasses ) {
				thisel.className += " salastread_readwithnewthread";
			}
			unvisitDecolors = setReadWithNewColors(doc, thisel, "TD");
			knownLastPostID = GetLastPostID(threadid);
		} else {
			if ( setClasses ) {
				thisel.className += " salastread_readthread";
			}
			unvisitDecolors = setReadColors(doc, thisel, "TD");
		}

		var threadIconOrder = persistObject.string_threadIconOrder;
		for (var j=0; j<THREAD_ICON_COUNT; j++) {
			if ( threadIconOrder.indexOf(String(j)) == -1 ) {
				threadIconOrder = String(threadIconOrder) + String(j);
			}
		}

		var thtml = topictitletd.innerHTML;
		var ntable = doc.createElement("table");
		var ntbody = doc.createElement("tbody");
		var ntr = doc.createElement("tr");
		var ntd0 = doc.createElement("td");
		var ntd1 = doc.createElement("td");
		var ntd2 = doc.createElement("td");
		ntr.appendChild(ntd0);
		ntr.appendChild(ntd1);
		ntr.appendChild(ntd2);
		ntbody.appendChild(ntr);
		ntable.appendChild(ntbody);
		ntable.style.width = "100%";
		ntable.style.borderCollapse = "collapse";
		ntable.style.border = "none";
		ntd0.style.border = "none";
		ntd1.style.border = "none";
		ntd2.style.border = "none";
		ntd0.style.background = "transparent";
		ntd1.style.background = "transparent";
		ntd2.style.background = "transparent";
		ntd0.style.padding = "0px";
		ntd1.style.padding = "0px";
		ntd2.style.padding = "0px";
		ntd0.style.width = "1px";
		ntd1.style.width = "99%";
		ntd2.style.width = "1px";
		ntd2.style.whiteSpace = "nowrap";
		ntd2.style.textAlign = "right";
		topictitletd.innerHTML = "";

		// actually pretty slow
		//while ( topictitletd.firstChild != null ) {
		//   var el = topictitletd.firstChild;
		//   topictitletd.removeChild(el);
		//   ntd1.appendChild(el);
		//}

		topictitletd.appendChild(ntable);
		ntd1.innerHTML = thtml;

		var iconTargetElement = ntd2;
		//var iconTargetElement = topictitletd;

		while ( threadIconOrder ) {
			var thisicon = threadIconOrder.substring(0,1);
			threadIconOrder = threadIconOrder.substring(1);
			if ( thisicon == 1 ) {
				if ( !knownLastPostID && persistObject.toggle_alwaysShowGoToLastIcon ) {
					knownLastPostID = GetLastPostID(threadid);
				}
				if (knownLastPostID) {
					if ( persistObject.toggle_showGoToLastIcon ) {
						//iconTargetElement.insertBefore(createGoToLastReadPostButton(doc, knownLastPostID), topictitletd.firstChild);
						iconTargetElement.appendChild(createGoToLastReadPostButton(doc, knownLastPostID));
					}
				}
			}
			else if ( thisicon == 2 ) {
				if ( persistObject.toggle_showUnvisitIcon ) {
					//iconTargetElement.insertBefore( createUnvisitButton(doc, threadid, thisel, unvisitDecolors), topictitletd.firstChild );
					iconTargetElement.appendChild( createUnvisitButton(doc, threadid, thisel, unvisitDecolors, forumid) );
				}
			}
		}

		if ( cachedThreadEntry.getAttribute("star")=="1" ) {
			var ix = doc.createElement("img");
			ix.src = "chrome://salastread/content/star.png";
			ix.style.paddingRight = "5px";
			ix.style.display = "block";
			ntd0.style.width = "1px";
			ntd0.appendChild(ix);
		} else {
			ntd0.style.display = "none";
		}

		var hasPostedInThread = GetPostedInThread(threadid);
		if (hasPostedInThread) {
			if ( setClasses ) {
				thisel.className += " salastread_postedinthread";
			}
			topicretd.style.backgroundColor = persistObject.color_postedInThreadRe;
			if ( !persistObject.toggle_disableGradients ) {
				var bgtohighlight = persistObject.color_postedInThreadReHighlight;
				topicretd.style.backgroundImage = "url(x-salr-gradientpng:"+
				SALRHexToNumber( bgtohighlight.substring(1,3) ) + "," +
				SALRHexToNumber( bgtohighlight.substring(3,5) ) + "," +
				SALRHexToNumber( bgtohighlight.substring(5,7) ) + "," +
				"33)";
				topicretd.style.backgroundRepeat = "repeat-x";
			}
			topicretd.style.fontWeight = "bold";
		}

		if ( cachedThreadEntry.getAttribute("lastreplyct") ) {
			var lastreplyct = 0 + cachedThreadEntry.getAttribute("lastreplyct");
			var curreplyct = 0 + topicretd.firstChild.firstChild.nodeValue;
			if (curreplyct > lastreplyct) {
				var newsp = doc.createElement("span");
				newsp.className = "salastread_newreplycount";
				newsp.appendChild(doc.createTextNode(" ("+ (curreplyct-lastreplyct)+")"));
				topicretd.appendChild(newsp);
			}
		}
	}
}

//
//
//
function handleForumDisplay(e) {
	//alert("forumdisplay");
	var doc = e.originalTarget;
	SALR_SearchForThreadPages(doc, "forum");

	//Replace post button
	if (persistObject.toggle_useQuickQuote) {
		var postbutton = selectSingleNode(doc, doc, "//UL[@class='postbuttons']//LI//A/IMG[contains(@src,'forum-post')]");
		if (postbutton) {
			makeQuickPostButton(undefined, doc, postbutton);
		}
	}


	// Snag Forum Moderators
	if ( persistObject.forumListXml ) {
		var saveXml = false;
		var fxml = persistObject.forumListXml;
		var mNodeContainer = selectSingleNode(doc, doc.body, "TABLE/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[2]/TD[1]/DIV[contains(text(),'(Mods:')]");
		if (mNodeContainer) {
			var fidmatch = doc.location.href.match(/forumid=(\d+)/i);
			if (fidmatch) {
				var forumid = fidmatch[1];
				var mods = new Array();
				var modnames = new Array();
				var mNodes = selectNodes(doc, mNodeContainer, ".//A");
				for (var i=0; i<mNodes.length; i++) {
					var xhrefuid = mNodes[i].href.match(/userid=(\d+)/i);
					if (xhrefuid) {
						mods.push( xhrefuid[1] );
						modnames.push( SALR_MakeClassSafe( mNodes[i].innerHTML ) );
					}
				}
				var flForumEl = selectSingleNode( fxml, fxml, "//forum[@id='"+forumid+"']" );
				if ( flForumEl ) {
					flForumEl.setAttribute("mods", mods.join(","));
					flForumEl.setAttribute("modnames", modnames.join(","));
					saveXml = true;
				}
			}
		}
		if (saveXml) {
			persistObject.forumListXml = fxml;  // forces a save
		}
	}

	// Highlight Threads
	var gotOne = false;
	var resarray = selectNodes(doc, doc, "//TR[@class='thread']");
	for (var x=0; x<resarray.length; x++) {
		var thisel = resarray[x];
		if ( thisel.nodeName == "TR" ) {
			var isunread = false;
			var titleNode = selectSingleNode(doc, thisel, "TD[@class='title']");
			var threadLink = selectSingleNode(doc, titleNode, "A[1]");
			if (threadLink==null)
			continue;
			var timatch = threadLink.href.match(/threadid=(\d+)/);
			var threadid = timatch[1];
			gotOne = true;
			var lpdtnode = selectSingleNode(doc, thisel, "TD[@class='lastpost']/DIV[@class='date']");
			var lpdttext = lpdtnode.innerHTML;
			lpdttext = StripSpaces(lpdttext);
			var lpdtm = lpdttext.match(/^(\d\d\:\d\d) (...) (\d\d), (\d\d\d\d)$/);
			if (!lpdtm) {
				return;
			}
			var lptime = lpdtm[1];
			var lpdate = lpdtm[2] + " " + lpdtm[3] + ", " + lpdtm[4];

			var forumid = 0;
			var fidmatch = doc.location.href.match(/forumid=(\d+)/i);
			if (fidmatch) {
				forumid = fidmatch[1];
			}
			var isFYAD = (forumid == 26);
			var isAskTell = (forumid == 158);
			if (isFYAD) {
				SALR_SilenceLoadErrors = true;
			}
			var setClasses = 1;
			var topictitletd = selectSingleNode(doc, thisel, "TD[@class='title']");
			var topicretd = selectSingleNode(doc, thisel, "TD[@class='replies']");

			// Here be where last read icons and new posts counts gets inserted
			setUpThreadIcons(doc,thisel,threadid,lpdate,lptime,isFYAD,setClasses,topictitletd,topicretd,forumid);

			// Here be where to grab OP
			var ulinknode = selectSingleNode(doc, thisel, "TD[@class='author']/A[contains(@href,'action=getinfo')]");
			if (ulinknode) {
				var userid = 0;
				var uidmatch = ulinknode.href.match(/userid=(\d+)/i);
				if ( uidmatch ) {
					userid = uidmatch[1];
				}
				var uname = ulinknode.firstChild.nodeValue;
				uname = uname.replace(/[^A-Z0-9]/gi, "_");
				ulinknode.className += " somethingawfulforum_userlink_"+uname;
				if ( SALR_IsModerator(userid, forumid) ) {
					ulinknode.className += " somethingawfulforum_userlinkMODERATOR";
				}
				persistObject.StoreOPData(threadid, userid);
			}

			// Here be insertion of class name in the killed by column
			var ulinknodeb = selectSingleNode(doc, thisel, "TD[@class='lastpost']/A[@class='author'][contains(@href,'goto=lastpost')]");
			if (ulinknodeb) {
				var uname = ulinknodeb.firstChild.nodeValue;
				uname = uname.replace(/[^A-Z0-9]/gi, "_");
				ulinknodeb.className += " somethingawfulforum_userlink_"+uname;
				if ( SALR_IsModerator(uname, forumid) ) {
					ulinknodeb.className += " somethingawfulforum_userlinkMODERATOR";
				}
			}

		}
	}


	if (gotOne) {
		var csstxt = SALR_MakeForumDisplayCSS();
		//alert("csstxt =\n"+csstxt);
		var cssObj = doc.createElement("style");
		cssObj.type = "text/css";
		cssObj.innerHTML = csstxt;
		doc.getElementsByTagName('head')[0].appendChild(cssObj);
	}

	return resarray.length;
}

/*
function SALR_CreateOPFunc(threadid, uid) {
return function() {
persistObject._cachedOP = { t: threadid, op: uid };
};
}
*/

function SALR_MakeClassSafe(unsafestr) {
	var result = unsafestr.replace(/[^A-Za-z0-9]/,"_");
	return result;
}

function createGoToLastReadPostButton(doc, lkpid) {
	var golink = doc.createElement("A");
	golink.href = "http://forums.somethingawful.com/showthread.php?s=&postid="+lkpid+"#post"+lkpid;
	golink.className = "salastreadicon";
	var goimg = doc.createElement("IMG");
	goimg.src = persistObject.url_goToLastReadPost;
	//goimg.style.cssFloat = "right";
	goimg.style.border = "none";
	goimg.style.marginLeft = "3px";
	golink.appendChild(goimg);
	return golink;
}

function createUnvisitButton(doc, threadid, topicrow, unvisitDecolors, forumid) {
	var dellink = doc.createElement("A");
	dellink.href = "javascript:void(0);";
	dellink.className = "salastreadicon";
	dellink.id = "salastread_dellink" + threadid;
	dellink.addEventListener("click", function(ce) { unvisitThread(doc, persistObject, threadid, topicrow, unvisitDecolors, forumid); }, true);
	var delimg = doc.createElement("IMG");
	delimg.src = persistObject.url_markThreadUnvisited;
	//delimg.style.cssFloat = "right";
	delimg.style.border = "none";
	delimg.style.marginLeft = "3px";
	dellink.appendChild(delimg);
	return dellink;
}

function unvisitThread(doc, pobj, threadid, topicrow, unvisitDecolors, forumid) {
	//alert("unvisiting "+threadid);
	try {
		var xmlDoc = pobj.xmlDoc;
		var threads = selectNodes(xmlDoc, xmlDoc, "/salastread/thread[@id='"+threadid+"']");
		for (var i=0; i<threads.length; i++) {
			threads[i].parentNode.removeChild(threads[i]);
		}
		if ( forumid == 0 ) {
			resetUnreadColors(unvisitDecolors);
		} else {
			if ( !persistObject.toggle_dontHighlightThreads ) {
				var threadrows = selectNodes(doc, topicrow, ".");
				for (var x=0; x<threadrows.length; x++) {
					threadrows[x].className = "thread salastread_thread_" + threadid + " salastread_unreadthread";
				}
			}
		}

		var icons = selectNodes(doc, topicrow, ".//A[@class='salastreadicon']");
		for (var j=0; j<icons.length; j++) {
			icons[j].parentNode.removeChild(icons[j]);
		}
		invalidateThreadCache();
		//pobj.SaveXML();
		persistObject.RemovePostDataSQL(threadid);
	} catch(e) { alert ("SALastRead unvisit fail: "+e); };
}

function replaceEmoticons(rawhtml) {
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/emot-crying.gif" alt="" border="0">/g,":cry:");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/emot-(.*?)\.gif" alt="" border="0">/g,":$1:");
	rawhtml = rawhtml.replace(/<img src="http:\/\/i\.somethingawful\.com\/forumsystem\/emoticons\/emot-(.*?)\.gif" alt="" border="0">/g,":$1:");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/frown.gif" alt="" border="0">/g,":(");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/smile.gif" alt="" border="0">/g,":)");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/confused.gif" alt="" border="0">/g,":confused:");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/cool.gif" alt="" border="0">/g,":cool:");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/biggrin.gif" alt="" border="0">/g,":D");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/mad.gif" alt="" border="0">/g,":mad:");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/redface.gif" alt="" border="0">/g,":o");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/rolleyes.gif" alt="" border="0">/g,":rolleyes:");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/wink.gif" alt="" border="0">/g,";)");
	rawhtml = rawhtml.replace(/<img src="http:\/\/forumimages\.somethingawful\.com\/images\/smilies\/wink.gif" alt="" border="0">/g,";)");
	rawhtml = rawhtml.replace(/<img src="http:\/\/i\.somethingawful\.com\/mjolnir\/images\/livestock~01-14-04-whore.gif" alt="" border="0">/g,";-*");
	return rawhtml;
}

function getQuoteCodeFromButton(doc,quotebutton,postername) {
	/*
	var thisel = quotebutton;
	while (thisel && !thisel.className.match(/post\d+/)) {
	thisel = thisel.parentNode;
	}
	if (!thisel)
	return "";
	var tid = thisel.SALR_threadid;
	if (!tid) return "";

	window.__salastread_quotepostid = tid;
	*/
	return"";
}

function convertPLTag(message) {
	return message.replace(/\[PL=(.*?)\](.*?)\[\/PL\]/g,"[URL=http://forums.somethingawful.com/showthread.php?s=&postid=$1#post$1]$2[/URL]");
	//return message.replace(/\[PL=(.*?)\](.*?)\[\/PL\]/g,"[URL=http://forums.somethingawful.com/showthread.php?s=&action=showpost&postid=$1]$2[/URL]");
}

function parsePLTagsInEdit(tarea) {
	var xtxt = tarea.value;
	tarea.value = convertPLTag(xtxt);
}

var quickquotewin = null;

function releaseQuickQuoteVarsWithClose() {
	quickquotewin.close();
}

function releaseQuickQuoteVars() {
	window.__salastread_quotedoc = null;
	window.__salastread_quotetext = null;
	window.__salastread_quotethreadid = null;
	window.__salastread_quotepostid = null;
	window.__salastread_alreadypostedinthread = null;
	window.__salastread_needretrieval = null;
	quickQuoteSubmitting = false;
	quickquotewin = null;
}

function quickQuoteAddHidden(doc,form,name,value) {
	var newel = doc.createElement("INPUT");
	newel.type = "hidden";
	newel.name = name;
	newel.value = value;
	form.appendChild(newel);
}

function quickQuoteAddFile(doc,form,name,value) {
	var newel = doc.createElement("INPUT");
	newel.type = "file";
	newel.name = name;
	newel.value = value;
	form.appendChild(newel);
}

var quickQuoteSubmitting = false;
var salastread_savedQuickReply = "";
var salastread_savedQuickReplyThreadId = "";

function quickQuoteSubmit(message, parseurl, subscribe, disablesmilies, signature, subtype, formkey, attachfile) {
	try {
		message = convertPLTag(message);
		salastread_savedQuickReply = message;
		salastread_savedQuickReplyThreadId = window.__salastread_quotethreadid;
		//alert("here");
		var doc = window.__salastread_quotedoc;
		var newform = doc.createElement("FORM");
		newform.style.display = "none";
		newform.action = "http://forums.somethingawful.com/newreply.php";
		if (!window.__salastread_quotethreadid)
		newform.action = "http://forums.somethingawful.com/newthread.php";
		if (quickquotewin.__salastread_is_edit)
		newform.action = "http://forums.somethingawful.com/editpost.php";
		newform.method = "post";
		newform.enctype = "multipart/form-data";
		quickQuoteAddHidden(doc,newform,"s","");
		if (window.__salastread_quotethreadid) {
			if (quickquotewin.__salastread_is_edit) {
				quickQuoteAddHidden(doc,newform,"action","updatepost");
				quickQuoteAddHidden(doc, newform, "postid", window.__salastread_quotepostid);
			}
			else {
				quickQuoteAddHidden(doc,newform,"action","postreply");
				quickQuoteAddHidden(doc,newform,"threadid", window.__salastread_quotethreadid);
			}
		}
		else {
			quickQuoteAddHidden(doc,newform,"action","postthread");
			quickQuoteAddHidden(doc, newform, "forumid",  quickquotewin.__salastread_quickpost_forumid);
			quickQuoteAddHidden(doc, newform, "iconid", quickquotewin.document.getElementById('posticonbutton').iconid);
			quickQuoteAddHidden(doc, newform, "subject", quickquotewin.document.getElementById('subject').value);
		}
		quickQuoteAddHidden(doc,newform,"parseurl", parseurl ? "yes" : "");
		quickQuoteAddHidden(doc,newform,"email", subscribe ? "yes" : "");
		quickQuoteAddHidden(doc,newform,"disablesmilies", disablesmilies ? "yes" : "");
		quickQuoteAddHidden(doc,newform,"signature", signature ? "yes" : "");
		quickQuoteAddHidden(doc,newform,"message", message);
		quickQuoteAddHidden(doc,newform,"MAX_FILE_SIZE", "2097152");
		quickQuoteAddHidden(doc,newform,"formkey", formkey);
		if (attachfile!="") {
			quickQuoteAddFile(doc,newform,"attachment", attachfile);
		}
		newform.__submit = newform.submit;
		if (window.__salastread_quotethreadid) {
			if (subtype=="submit") {
				quickQuoteAddHidden(doc,newform,"submit","Submit Reply");
				markThreadReplied(persistObject, window.__salastread_quotethreadid);
			} else {
				quickQuoteAddHidden(doc,newform,"preview","Preview Reply");
			}
		}
		else {
			quickQuoteAddHidden(doc,newform,"preview","Preview Post");
		}
		doc.body.appendChild(newform);
		//alert(newform.innerHTML);
		quickQuoteSubmitting = true;
		newform.__submit();
		quickquotewin.close();
	} catch(e) { alert("err: "+e); }
}

function salastread_windowOnBeforeUnload(e) {
	if ( persistObject._killed==true ) { return; }
	if ( e.originalTarget == window.__salastread_quotedoc ) {
		if (quickQuoteSubmitting) {
			return true;
		}
		/*
		alert("If you navigate away from this page, the Quick Reply window will close, since it will "+
		"no longer have a page to target to submit the reply to (this will probably be fixed "+
		"in a future release).  If you want to cancel this navigation, choose 'Cancel' in the "+
		"next dialog box that will appear.");
		e.stopPropagation();
		e.preventDefault();
		return false;
		*/
		if (quickquotewin && !quickquotewin.closed) {
			quickquotewin.detachFromDocument();
		}
		return true;
	}
}

var SALR_PageTimerCount = 0;

function SALR_IncTimer() {
	SALR_PageTimerCount++;
}

function SALR_DecTimer() {
	SALR_PageTimerCount--;
}

function SALR_TimerTick() {
	if ( SALR_PageTimerCount > 0 && persistObject ) {
		persistObject.PingTimer();
	}
}

function SALR_SyncTick(force,trace) {
	var xforce = force ? true : false;
	trace = (trace==true) ? true : false;
	if (persistObject) {
		var res;
		if (trace)
		res = persistObject.PerformRemoteSync(xforce, function(){}, function(a){alert(a);});
		else
		res = persistObject.PerformRemoteSync(xforce, function(){}, function(a){});
		if (xforce) { alert("res.bad = "+res.bad+"\nres.msg = "+res.msg); }
	}
}

function salastread_windowOnUnload(e) {
	if ( persistObject._killed==true ) { return; }
	if ( e.originalTarget == window.__salastread_quotedoc ) {
		//releaseQuickQuoteVarsWithClose();
		releaseQuickQuoteVars();
	}
	if ( e.originalTarget.__salastread_processed ) {
		SALR_DecTimer();
		persistObject.SaveTimerValue();
	}
	//   var pageTimer = e.originalTarget.__SALASTREAD_PAGETIMER;
	//   if (pageTimer) {
	//      pageTimer.Finalize();
	//      e.originalTarget.__SALASTREAD_PAGETIMER = null;
	//      var newPageTimers = new Array();
	//      for (var i=0; i<thisWindowPageTimers.length; i++) {
	//        if ( thisWindowPageTimers[i] != pageTimer ) {
	//           newPageTimers.push( thisWindowPageTimers[i] );
	//        }
	//      }
	//      thisWindowPageTimers = newPageTimers;
	//   }
}

function cleanupLostPageTimers() {
	// because attaching to the unload event dynamically doesn't appear to work ...
	var cont = document.getElementById("content");
	var browsers = cont.browsers;
	var newPageTimers = new Array();
	for (var i=0; i<thisWindowPageTimers.length; i++) {
		var thisTimer = thisWindowPageTimers[i];
		var gotThisOne = 0;
		for (var j=0; j<browsers.length; j++) {
			var thisBrowser = browsers[j];
			if (thisBrowser.contentDocument && thisBrowser.contentDocument.__SALASTREAD_PAGETIMER==thisTimer) {
				gotThisOne = 1;
				newPageTimers.push(thisTimer);
			}
		}
		if (gotThisOne==0) {
			thisTimer.Finalize();
		}
	}
	thisWindowPageTimers = newPageTimers;
}

//function quickQuoteButtonClick(evt,threadid,/*doc,quotebutton,*/postername,isDoubleClick,hasQuote) {
function quickQuoteButtonClick(evt/*,threadid,postername,isDoubleClick,hasQuote*/) {
	var doc = evt.originalTarget.ownerDocument;
	var quotebutton = evt.originalTarget;
	var threadid = quotebutton.__salastread_threadid;
	var forumid = quotebutton.SALR_forumid;
	var postername = quotebutton.__salastread_postername;
	var hasQuote = quotebutton.__salastread_hasQuote;
	var is_edit = quotebutton.is_edit;
	var isDoubleClick = 0;

	if ( persistObject.__QuickQuoteWindowObject && !persistObject.__QuickQuoteWindowObject.closed ) {
		quickquotewin = persistObject.__QuickQuoteWindowObject;
	}

	window.__salastread_needretrieval = false;
	window.__salastread_quotedoc = doc;
	if (hasQuote) {
		// don't deparse anymore since we need the formkey anyway
		// on second thought, still need to call so quotepostid is set
		window.__salastread_quotetext = getQuoteCodeFromButton(doc, quotebutton, postername);
		window.__salastread_quotepostid = quotebutton.__salastread_postid;
		//window.__salastread_quotetext = "";
		if ( window.__salastread_quotetext == "" ) {
			window.__salastread_needretrieval = true;
		}
	} else {
		window.__salastread_quotetext = "";
		window.__salastread_quotepostid = null;
	}
	if (forumid) window.__salastread_needretrieval = true;
	window.__salastread_quotethreadid = threadid;
	window.__salastread_alreadypostedinthread = GetPostedInThread(threadid);
	if (!isDoubleClick && quickquotewin && !quickquotewin.closed) {
		try {
			//quickquotewin.addQuoteText(window.__salastread_quotetext);
			if (hasQuote) {
				quickquotewin.addQuoteFromPost(window.__salastread_quotepostid);
			}
			quickquotewin.focus();
		} catch(ex) {
			quickquotewin = window.open("chrome://salastread/content/quickquote.xul",
			"quickquote",
			"chrome, resizable=yes, width=800, height=400");
		}
	} else {
		quickquotewin = window.open("chrome://salastread/content/quickquote.xul",
		"quickquote",
		"chrome, resizable=yes, width=800, height=400");
	}
	if (quickquotewin) {
		persistObject.__QuickQuoteWindowObject = quickquotewin;
		quickquotewin.__salastread_quickpost_forumid = forumid;
		quickquotewin.__salastread_is_edit = is_edit;
	}
	return false;
}

function __unused() {
	try {
		var newdiv = doc.createElement("DIV");
		//newdiv.message = "woo woo woo";
		newdiv.style.position = "fixed";
		newdiv.style.top = "2%";
		newdiv.style.left = "2%";
		newdiv.style.width = "96%";
		newdiv.style.height = "50%";
		newdiv.style.zIndex = "13294945";
		newdiv.style.border = "1px solid #c1c1c1";
		newdiv.style.MozBinding = "url('chrome://salastread/content/quickquote.xml#quickquote')";
		doc.body.appendChild(newdiv);
		//newdiv.setAttribute("message", getQuoteCodeFromButton(doc,quotebutton) );
		newdiv.message = getQuoteCodeFromButton(doc,quotebutton,postername);
	}
	catch (e) {
		alert("err: "+e);
	}
	return false;
}

function attachQuickQuoteHandler(threadid,doc,quotebutton,postername,hasQuote,postid) {
	quotebutton.__salastread_threadid = threadid;
	quotebutton.__salastread_postid = postid;
	quotebutton.__salastread_postername = postername;
	quotebutton.__salastread_hasQuote = hasQuote;
	quotebutton.addEventListener("click", quickQuoteButtonClick, true);
	//quotebutton.onclick = function(evt) { return quickQuoteButtonClick(evt,threadid,/*doc,quotebutton,*/postername,0,hasQuote); };
	//quotebutton.ondblclick = function(evt) { return quickQuoteButtonClick(evt,threadid,/*doc,quotebutton,*/postername,1,hasQuote); };
}

var SALR_debugLog = new Array();
function addInternalDebugLog(msg) {
	SALR_debugLog.push( (new Date()).toString() +": "+msg );
	if ( SALR_debugLog.length > 10 ) {
		SALR_debugLog.shift();
	}
}

function SALR_ProcessPostImages(thisel) {
	var doc = thisel.ownerDocument;
	if ( persistObject.toggle_convertTextToImage ) {
		var mayBeNws = false;
		if ( persistObject.toggle_dontTextToImageIfMayBeNws ) {
			var ptext = thisel.innerHTML;
			if ( ptext.match(/nsfw/i) || ptext.match(/nws/i) ||
			ptext.match(/work safe/i) || ptext.match(/safe for work/i) ||
			ptext.match(/nms/i) ) {
				mayBeNws = true;
			}
		}
		if (!mayBeNws)
		SALR_TextToImage(thisel);
	}


	if (persistObject.toggle_thumbnailAllImages) {
		setTimeout(function() {

			var bodyimagenodes = selectNodes(doc, thisel, "TBODY/TR[1]/TD[2]/descendant::IMG");
			for (var lnum=0; lnum<bodyimagenodes.length; lnum++) {
				var thisimage = bodyimagenodes[lnum];
				thisimage.className += " SALR_need_thumbnailing";
				thisimage.addEventListener("load", SALR_PostImageResize, false);
				thisimage.addEventListener("resize", SALR_PostImageResize, false);
				thisimage.addEventListener("click", SALR_PostImageClick, false);
				thisimage.addEventListener("mouseout", SALR_PostImageMouseOut, false);
				thisimage.addEventListener("mouseover", SALR_PostImageMouseOver, false);
				var xx = { target: thisimage };
				SALR_PostImageResize(xx);
			}
		},1);
	}
}

// Ensure these correspond to the settings in thumbnail-images.css
var SALR_THUMBNAIL_MAX_WIDTH = 250;
var SALR_THUMBNAIL_MAX_HEIGHT = 250;

function SALR_PostImageClick(e) {
	var image = e.target;
	if (image.className.indexOf("SALR_thumbnail_fullsize")!=-1) {
		var cx = image.className.split(" ");
		var ncx = new Array();
		for (var i=0; i<cx.length; i++) {
			if (cx[i]!="SALR_thumbnail_fullsize")
			ncx.push(cx[i]);
		}
		image.className = ncx.join(" ");
	} else {
		image.className += " SALR_thumbnail_fullsize";
	}
	SALR_PostImageResize(e);
}

function SALR_PostImageMouseOver(e) {
	SALR_PostImageResizerShowHide(true, e);
}

function SALR_PostImageMouseOut(e) {
	SALR_PostImageResizerShowHide(false, e);
}

function SALR_PostImageResizerShowHide(show, e) {
	var image = e.target;
	var doc = image.ownerDocument;
	if (!image.__SALR_ThumbnailControl) {
		SALR_BuildThumbnailControl(doc,image);
		SALR_ToggleThumbnailControl(image,true)
	}
	if (image.SALR_imageResizable == undefined && image.className.indexOf("SALR_thumbnail_fullsize") == -1) {
		if(image.offsetWidth == image.naturalWidth && image.offsetHeight == image.naturalHeight) {
			image.SALR_imageResizable = false
		} else {
			image.SALR_imageResizable = true
		}
	}

	if(image.SALR_imageResizable != undefined && !image.SALR_imageResizable) {
		return
	}

	if (image.__SALR_ThumbnailControl) {
		if (show) {
			image.__SALR_ThumbnailControl.style.display = "block";
			if (image.__SALR_ThumbnailHideTimer) {
				clearTimeout(image.__SALR_ThumbnailHideTimer);
				image.__SALR_ThumbnailHideTimer = null;
			}
		} else {
			image.__SALR_ThumbnailHideTimer = setTimeout(function() {
				image.__SALR_ThumbnailHideTimer = null;
				image.__SALR_ThumbnailControl.style.display = "none";
			}, 1000);
		}
	}
}


function SALR_PostImageResize(e) {
	var image = e.target;
	var doc = image.ownerDocument;

	if (!image.__SALR_ThumbnailControl) {
		SALR_BuildThumbnailControl(doc,image);
	}

	if (image.className.indexOf("SALR_thumbnail_fullsize")!=-1) {
		SALR_ToggleThumbnailControl(image,true)
	} else {
		SALR_ToggleThumbnailControl(image,false)
	}
}

function SALR_ToggleThumbnailControl(image,up) {
	var tc = image.__SALR_ThumbnailControl;
	var tci = tc.firstChild;
	if(up) {
		tci.__up = true;
		tci.src = "chrome://salastread/content/scale_image_up.png";
	} else {
		tci.__up = false;
		tci.src = "chrome://salastread/content/scale_image.png";
	}
}

function SALR_BuildThumbnailControl(doc,image) {
	var outer = doc.createElement("div");
	outer.style.position = "absolute";
	outer.style.display = "none";
	var inner = doc.createElement("img");
	inner.src = "chrome://salastread/content/scale_image_up.png";
	inner.style.position = "relative";
	inner.style.top = "-11px";
	inner.style.left = "-11px";
	inner.style.width = "22px";
	inner.style.height = "22px";
	inner.style.border = "none";
	inner.style.cursor = "pointer";
	inner.onclick = function() { SALR_PostImageClick( {target: image} ); return false; };
	inner.onmouseover = function() { SALR_PostImageMouseOver( {target: image} ); return false; };
	inner.onmouseout = function() { SALR_PostImageMouseOut( {target: image} ); return false; };
	outer.appendChild(inner);
	image.parentNode.insertBefore(outer, image);
	image.__SALR_ThumbnailControl = outer;
}

function SALR_TextToImage(thisel) {
	var doc = thisel.ownerDocument;
	var bodylinknodes = selectNodes(doc, thisel, "TBODY/TR[1]/TD[2]/descendant::A");
	for (var lnum=0; lnum<bodylinknodes.length; lnum++) {
		var isimage = false;
		var thislink = bodylinknodes[lnum];
		var imgurl = thislink.href;
		if ( imgurl.match(/\.(gif|jpg|jpeg|png)$/i) ) {
			isimage = true;
		}
		var thmatch = imgurl.match(/^(.*)\.th(\..*)$/);
		if (thmatch) {
			imgurl = thmatch[1]+thmatch[2];
		}
		if ( imgurl.indexOf("?")!=-1 ) {
			isimage = false;
		}
		if ( selectSingleNode(doc, thislink, "IMG") ) {
			isimage = false;
		}
		if (isimage) {
			var abortTTI = false;
			if ( persistObject.toggle_dontTextToImageInSpoilers ) {
				var cel = thislink;
				while (cel!=null) {
					if (cel.className.indexOf("spoiler")!=-1) {
						abortTTI = true;
						break;
					}
					if (cel.className.indexOf("somethingawfulforum_postby")!=-1) {
						break;
					}
					cel = cel.parentNode;
				}
			}
			if (!abortTTI) {
				var nimg = doc.createElement("img");
				if ( thislink.childNodes.length==1 &&
				thislink.firstChild.nodeName=="#text" &&
				thislink.firstChild.nodeValue.indexOf("http")==0 ) {
					// special case to replace a link containing only the url text completely
					thislink.removeChild(thislink.firstChild);
				}
				if ( thislink.nextSibling ) {
					thislink.parentNode.insertBefore(nimg, thislink.nextSibling);
				} else {
					thislink.parentNode.appendChild(nimg);
				}
				nimg.style.border = "2px dotted red";
				nimg.src = imgurl;
				nimg.title = "Text link converted to image automatically by SALR";
				if ( persistObject.toggle_shrinkTextToImages ) {
					setupThumbnailImage(nimg,false,true);
				}
			}
		}
	}
}

function handleShowThread(e) {
	
	var doc = e.originalTarget;

	if (doc.body.id != "something_awful" && doc.body.id != "all")
	return;
	var inFYAD = false;
	var inBYOB = false;

	var isloggedin = true;
	//if ( selectSingleNode(doc, doc.body, "TABLE/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[1]/TD[1]//A[contains(@href,'action=loginform')]") ) {
	if ( doc.getElementById("notregistered") ) {
		isloggedin = false;
	}

	// Grab the go to dropdown
	if ( !persistObject.gotForumList ) {
		// Don't update from the dropdown in the gas chamber, because it contains Who's Online for some reason.
		var gasnode = selectSingleNode(doc, doc.body, "//TABLE[@align='center']/TBODY/TR[1]/TD[1]//B[1]/A[3][contains(@href,'forumdisplay.php')][contains(@href,'forumid=25')]");
		if (!gasnode) {
			var selectnode = selectSingleNode(doc, doc.body, "//SELECT[@name='forumid']");
			if (selectnode) {
				grabForumList(e, selectnode);
				persistObject.gotForumList = true;
			}
		}
	}

	var forumid = 0;
	//var forumidnodes = selectNodes(doc, doc.body, "TABLE/TBODY/TR[1]/TD[1]/TABLE[@align='center']/TBODY/TR[1]/TD[1]/SPAN[@class='mainbodytextlarge']/B[1]/A[contains(@href,'forumdisplay.php')][contains(@href,'forumid=')]");
	var forumidnodes = selectNodes(doc, doc.getElementById("container"), "DIV[@class='breadcrumbs']/SPAN/B/A[contains(@href,'forumdisplay.php')][contains(@href,'forumid=')]");
	if (forumidnodes && forumidnodes.length>0) {
		forumid = forumidnodes[forumidnodes.length-1].href.match(/forumid=(\d+)/i)[1];
	}
	doc.__SALR_forumid = forumid;
	doc.body.className += " salastread_forum"+forumid
	//alert("forumid = "+forumid);
	if (forumid == 174)
	{
		inBYOB = true;
	}
	// Figure out the current threadid
	var threadid;
	var timatch = doc.location.href.match( /threadid=(\d+)/ );
	if ( timatch ) {
		threadid = timatch[1];
	} else {
		//var sublinknode = selectSingleNode(doc, doc.body, "//A[contains(@href,'member2.php')][contains(@href,'threadid=')]");
		var sublinknode = selectSingleNode(doc, doc.getElementById("container"), "DIV[@class='subscribe']/A[contains(@href,'member2.php')][contains(@href,'threadid=')]");
		if (sublinknode) {
			var hrefmatch = sublinknode.href.match( /threadid=(\d+)/ );
			if (hrefmatch) {
				//alert("here here [1] - " + hrefmatch[1]);
				threadid = hrefmatch[1];
			}
		}
	}
	if ( !threadid ) {
		return;
	}
	doc.__SALR_threadid = threadid;

	// used by the context menu to allow options for this thread
	doc.body.className += " salastread_thread_"+threadid;
	
	// DEBUG:
	slurpIntoThreadCache(threadid);
	if (cachedThreadEntry) {

		var needSave = false;
		/*
		if ( persistObject._cachedOP && persistObject._cachedOP.t == threadid ) {
		if ( cachedThreadEntry.getAttribute("op") != persistObject._cachedOP.op ) {
		cachedThreadEntry.setAttribute("op", persistObject._cachedOP.op);
		needSave = true;
		}
		}
		*/
		var sop = persistObject.GetOPFromData(threadid);
		if ( sop && sop != cachedThreadEntry.getAttribute("op") ) {
			cachedThreadEntry.setAttribute("op", sop);
			needSave = true;
		}

		var threadtitle = "";
		var titlematch = doc.title.match( /^The Something Awful Forums \- (.*)$/ );
		if (titlematch) {
			threadtitle = titlematch[1];
		} else {
			var titlematchb = doc.title.match( /^(.*) \- The Something Awful Forums$/ );
			if (titlematchb) {
				threadtitle = titlematchb[1];
			}
		}
		if (threadtitle != "") {
			//alert("thread title = "+titlematch[1]);
			if ( !cachedThreadEntry.getAttribute("title") || cachedThreadEntry.getAttribute("title") != threadtitle ) {
				cachedThreadEntry.setAttribute("title", threadtitle);
				needSave = true;
				//persistObject.SaveXML();
			}
		} else {
			//alert("XX thread title = "+doc.title);
		}

		if (needSave) {
			//persistObject.SaveXML();
			var threaddetails = new Array();
			threaddetails['id'] = threadid;
			threaddetails['title'] = cachedThreadEntry.getAttribute("title");
			threaddetails['lastviewdt'] = cachedThreadEntry.getAttribute("lastviewdt");
			threaddetails['op'] = cachedThreadEntry.getAttribute("op");
			persistObject.SavePostDataSQL(threaddetails);
		}
	}
	var lpbefore = 0;
	if (cachedThreadEntry) {
		lpbefore = cachedThreadEntry.getAttribute("lastpostid");
	}
	var lpafter = 0;
	//addInternalDebugLog("showthread.php handler, thread #"+threadid+", lpbefore="+lpbefore+", lpafter="+lpafter);
	
	// See if this thread is closed
	var threadClosed = false;
	//if ( selectSingleNode(doc, doc.body, "//IMG[@alt='Post A Reply'][contains(@src,'sa-closed.jpg')]") ) {
	if ( selectSingleNode(doc, doc.getElementById("container"), "DIV[@class='threadbar bottom']/UL[@class='postbuttons']/LI/A/IMG[@alt='Reply'][contains(@src,'closed')]") ) {
		threadClosed = true;
	}
	//alert("threadClosed = "+threadClosed);

	//var resarray = new Array();
	//if (inFYAD) {
	//   resarray = selectNodes(doc, doc.body, "TABLE/TBODY[1]/TR[1]/TD[2]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[2]/TD[1]/DIV[1]/FONT[1]");
	//} else {
	//   resarray = selectNodes(doc, doc.body, "TABLE/TBODY[1]/TR[1]/TD[2]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[2]/TD[1]/DIV[@class='mainbodytextsmall']");
	//}
	// XXX: remove // when font tags are closed
	var resarray = selectNodes(doc, doc.getElementById("thread"), "TABLE[contains(@id,'post')]");
	var needUpdate = false;
	var needCssInsert = false;
	var updateTo = null;
	var updateLastPostID = null;
	var isEven = false;
	doc.postlinks = new Array;
	for (var x=0; x<resarray.length; x++) {
		if (!(resarray[x].className.match(/ignored/))) {
			//var postdate = resarray[x].firstChild.nodeValue;
			var postbarnode = selectSingleNode(doc, resarray[x], "TBODY/TR[@class='postbar']");
			var userinfonode = selectSingleNode(doc, resarray[x], "TBODY/TR/TD[@class='userinfo']");
			if (isEven) {
				resarray[x].className += " salastread_even";
				//postbarnode.className += " salastread_even";
			} else {
				resarray[x].className += " salastread_odd";
				//postbarnode.className += " salastread_odd";
			}
			isEven = !isEven;
			var postdatenode = selectSingleNode(doc, postbarnode, "TD[@class='postdate']");
			if (postdatenode.firstChild.nodeName=="FONT") {
				postdatenode = postdatenode.firstChild;
			}
			var postdate = postdatenode.lastChild.nodeValue;

			postdate = StripSpaces(postdate.substring(0, postdate.length));
			//alert("postdate = "+postdate);
			//try {
			var posttime;
			//if (inFYAD) {
			//   posttime = StripSpaces(resarray[x].firstChild.nextSibling.firstChild.firstChild.nodeValue);
			//} else {
			//   posttime = StripSpaces(resarray[x].firstChild.nextSibling.firstChild.nodeValue);
			//}
			var pdmatch = postdate.match(/^(... \d\d, \d\d\d\d)\:? (\d\d\:\d\d)$/);
			if (pdmatch) {
				postdate = pdmatch[1];
				posttime = pdmatch[2];
			}
			//} catch (e) { resarray[x].style.backgroundColor = "red"; throw e; }
			var postdtvalue = ConvertLPDateTimeToNum(postdate, posttime);
			var thisel = resarray[x];
			//while ( thisel.nodeName != "TABLE" ) {
			//   thisel = thisel.parentNode;
			//}

			var postid = 0;
			//var postidlink = selectSingleNode(doc, thisel, "TBODY/TR[2]/TD[2]/TABLE/TBODY/TR[1]/TD[2]//A[contains(@href,'postid=')]");
			//if (postidlink) {
			//   var postidmatch = postidlink.href.match(/postid=(\d+)/);
			//   postid = postidmatch[1];
			//}
			// XXX: The // in the next xpath can be changed to / when unclosed font tags stop messing with the forum DOM tree
			var postlink = selectSingleNode(doc, postbarnode, "TD[@class='postdate']//A[contains(@href,'#')]").href;
			postid = postlink.match(/post(\d+)/)[1];
			//alert("postid = "+postid);

			if (postid>0)
			lpafter = postid;

			//var ilpdt = IsLPDateTimeNew(false, postdtvalue, threadid, postid);
			var ilpdt = (postid > lpbefore);
			if ( ilpdt ) {
				needUpdate = true;
				updateTo = postdtvalue;
				//var anchorval = selectNodes(doc, thisel, "TBODY/TR/TD/A[contains(@name,'post')]")[0];
				//var avmatch = anchorval.name.match( /\d+/ );
				//updateLastPostID = avmatch;
				updateLastPostID = postid;
				//if (inFYAD) {
				//   setUnseenPostFYADColors(doc, thisel, "TBODY/TR/TD");
				//} else {
				setUnseenPostColors(doc, thisel);
				//}
			} else {
				//if (inFYAD) {
				//   setSeenPostFYADColors(doc, thisel, "TBODY/TR/TD");
				//} else {
				setSeenPostColors(doc, thisel);
				//}
			}
			needCssInsert = true;
			//alert("post colors set");

			// Get classes...
			var thiselClassNameAdd = "";
			var posternodeClassNameAdd = "";
			var posternodeparentClassNameAdd = "";
			var rawpostername = "(unknown)";
			var postername = "(unknown)";
			var posteruserid = 0;
			//var posteridnode = selectNodes(doc, thisel, "TBODY/TR[2]/TD[2]/TABLE/TBODY/TR[1]/TD[1]/DIV/A[contains(@href,'action=getinfo')]")[0];
			//   The // can be / when font tags are closed
			var posteridnode = selectSingleNode(doc, postbarnode, "TD[@class='postlinks']/UL[@class='profilelinks']/LI//A[contains(@href,'action=getinfo')]");
			if (posteridnode) {
				var idmatch = posteridnode.href.match(/userid=(\d+)/);
				if (idmatch) {
					posteruserid = Number( idmatch[1] );
					thiselClassNameAdd += " somethingawfulforum_postbyid_"+posteruserid;
					posternodeClassNameAdd += " somethingawfulforum_usernameid_"+posteruserid;
				}
			}
			//var posternode;
			//if (inFYAD) {
			//   posternode = selectNodes(doc, thisel, "TBODY/TR/TD/FONT/B")[0];
			//} else {
			//   posternode = selectNodes(doc, thisel, "TBODY/TR[1]/TD[1]/DIV/B")[0];
			//}
			var posternode = selectSingleNode(doc, thisel, "TBODY/TR/TD[@class='userinfo']/DL[@class='userinfo']/DT[@class='author']");
			if (posternode) {
				postername = posternode.firstChild.nodeValue;
				if ( posternode.lastChild != posternode.firstChild )
				postername = posternode.lastChild.nodeValue;

				if ( !postername ) { // to deal with radiums new name
					postername = posternode.childNodes[2].childNodes[0].nodeValue;
				}
				posterarray = postername.split(/&nbsp;/);
				postername = posterarray.length == 1 ? posterarray[0] : posterarray[1];
				rawpostername = postername;
				postername = postername.replace(/[^A-Za-z0-9]/g,"_");
				thiselClassNameAdd += " somethingawfulforum_postby_"+postername;
				posternodeClassNameAdd += " somethingawfulforum_username_"+postername;
				posternodeparentClassNameAdd += " somethingawfulforum_parentusername_"+postername;
			}
			if (!inFYAD) {
				slurpIntoThreadCache(threadid);
				if ( cachedThreadEntry && cachedThreadEntry.getAttribute("op")==posteruserid ) {
					thiselClassNameAdd += " somethingawfulforum_postbyOP";
					posternodeClassNameAdd += " somethingawfulforum_usernameOP";
					posternodeparentClassNameAdd += " somethingawfulforum_parentusernameOP";
				}
				//if ( SALR_IsModerator( posteruserid, forumid ) ) {
				var modcheck = selectSingleNode(doc, userinfonode, "DL[@class='userinfo']/DT[@class='author']/IMG[@title='Moderator']");
				if (modcheck && isloggedin) {
					thiselClassNameAdd += " somethingawfulforum_postbyMODERATOR";
					posternodeClassNameAdd += " somethingawfulforum_usernameMODERATOR";
					posternodeparentClassNameAdd += " somethingawfulforum_parentusernameMODERATOR";
				}
				//var admincheck = selectNodes(doc, thisel, "TBODY/TR[2]/TD[2]/TABLE/TBODY/TR[1]/TD[2]/DIV/A[contains(@href,'modalert.php')]")[0];

				//Checking for admins is harder than it used to be :argh:
				var admincheck = selectSingleNode(doc, postbarnode, "TD[@class='postlinks']/UL[@class='postbuttons']/LI/A/IMG[contains(@src,'report')]");
				// check for an admin star, make sure it isn't a mod star
				var admincheck2 = selectSingleNode(doc, posternode, "IMG[contains(@src,'http')]");
				var admincheck3 = selectSingleNode(doc, posternode, "IMG[contains(@src, 'moderator')]");
				if (!admincheck && isloggedin) {
					if (admincheck2 && !admincheck3) {
						thiselClassNameAdd += " somethingawfulforum_postbyADMIN";
						posternodeClassNameAdd += " somethingawfulforum_usernameADMIN";
						posternodeparentClassNameAdd += " somethingawfulforum_parentusernameADMIN";
					}
				}
			}

			// Apply classes...
			if (thiselClassNameAdd!="") {
				thisel.className += thiselClassNameAdd;
			}
			if (posternode && posternodeClassNameAdd!="") {
				posternode.className += posternodeClassNameAdd;
				//if (persistObject.toggle_props) {
				//   if (postername == "biznatchio") {
				//      posternode.style.color = "red";
				//   }
				//}
			}
			if (posternode && posternodeparentClassNameAdd!="") {
				posternode.parentNode.className += posternodeparentClassNameAdd;
			}
			//alert("classes applied");

			//var titlenode = selectSingleNode(doc, thisel, "TBODY/TR[1]/TD[1]/DIV[3]");
			/*
			var titlenode = selectSingleNode(doc, thisel, "DL[@class='userinfo']/DD[@class='title']");
			if (titlenode) {
			titlenode.className += " customtitle";
			if ( persistObject.toggle_resizeCustomTitleText ) {
			var subnodes = selectNodes(doc, titlenode, ".//*");
			for (var i=0; i<subnodes.length; i++) {
			if ( subnodes[i].style ) {
			subnodes[i].style.fontSize = "8pt";
			}
			}
			}
			}
			*/

			if (persistObject.toggle_useQuickQuote && !threadClosed) {
				//var quotebutton = selectNodes(doc, thisel, "//IMG[@alt='Reply w/Quote']")[0];
				//   // to / when font tags are closed
				var quotebutton = selectSingleNode(doc, postbarnode, "TD[@class='postlinks']/UL[@class='postbuttons']/LI//A/IMG[contains(@src,'quote')]");
				if (quotebutton) {
					quotebutton.style.width = "12px !important";
					quotebutton.style.height = "20px !important";
					if(inBYOB){
						quotebutton.src = "chrome://salastread/content/byobarrow.gif";
					}else{
						quotebutton.src = "chrome://salastread/content/button-normalquote.gif";
					}
					quotebutton.alt = "Normal Reply w/Quote";

					var newquote = doc.createElement("IMG");
					if(inBYOB){
						newquote.src = "chrome://salastread/content/byob-qquote.gif";
					}else{
						newquote.src = "chrome://salastread/content/button-quickquote.gif";
					}
					newquote.alt = "Quick Reply w/Quote";
					newquote.border = "0"
					newquote.style.cursor = "pointer";
					attachQuickQuoteHandler(threadid,doc,newquote,rawpostername,1,postid);
					quotebutton.parentNode.parentNode.insertBefore(newquote, quotebutton.parentNode);
					//quotebutton.onclick = function(evt) { return quickQuoteButtonClick(evt,threadid,doc,quotebutton,postername); };
				}
				var quotebutton = selectSingleNode(doc, postbarnode, "TD[@class='postlinks']/UL[@class='postbuttons']/LI//A/IMG[contains(@src,'edit')]");
				if (quotebutton) {
					quotebutton.style.width = "12px !important";
					quotebutton.style.height = "20px !important";
					if(inBYOB){
						quotebutton.src = "chrome://salastread/content/byobarrow.gif";
					}else{
						quotebutton.src = "chrome://salastread/content/button-normaledit.gif";
					}
					quotebutton.alt = "Normal Reply w/Quote";

					var newquote = doc.createElement("IMG");
					if(inBYOB){
						newquote.src = "chrome://salastread/content/byob-qedit.gif";
					}else{
						newquote.src = "chrome://salastread/content/button-quickedit.gif";
					}
					newquote.alt = "Quick Reply w/Quote";
					newquote.border = "0"
					newquote.style.cursor = "pointer";
					newquote.is_edit = true;
					attachQuickQuoteHandler(threadid,doc,newquote,rawpostername,1,postid);
					quotebutton.parentNode.parentNode.insertBefore(newquote, quotebutton.parentNode);
					//quotebutton.onclick = function(evt) { return quickQuoteButtonClick(evt,threadid,doc,quotebutton,postername); };
				}
			}
			//alert("qq set");

			//if ( persistObject.toggle_fixBrokenQuotedLinks ) {
			/*
			if ( 1==1 ) {
			var bodylinknodes = selectNodes(doc, thisel, "TBODY/TR[1]/TD[2]/descendant::A");
			for (var lnum=0; lnum<bodylinknodes.length; lnum++) {
			var href = bodylinknodes[lnum].href;
			if ( href.substring(href.length-8) == "%3C/a%3E" ) {
			bodylinknodes[lnum].href = href.substring(0, href.length-8);
			} else {
			//DEBUG:
			}
			}
			}
			*/

			SALR_ProcessPostImages(thisel);
			//alert("images processed");

			if ( persistObject.toggle_insertPostTargetLink ||
			persistObject.toggle_insertPostLastMarkLink ) {
				if (postid!=0) {
					//var posttimenode;
					//if (inFYAD) {
					//   posttimenode = selectNodes(doc, thisel, "TBODY/TR[2]/TD[1]/DIV/FONT/FONT/B")[0];
					//} else {
					//   posttimenode = selectNodes(doc, thisel, "TBODY/TR[2]/TD[1]/DIV/B")[0];
					//}
					//  // to / when font tags are closed
					var posttimenode = selectSingleNode(doc, postbarnode, "TD[@class='postdate']//A");
					/*
					if (posttimenode && persistObject.toggle_insertPostTargetLink ) {
					var plink = doc.createElement("A");
					plink.href = "http://forums.somethingawful.com/showthread.php?s=&postid="+postid+"#post"+postid;
					plink.title = "Link directly to this post";
					plink.appendChild( doc.createTextNode("#") );
					posttimenode.appendChild(doc.createTextNode(" "));
					posttimenode.appendChild(plink);
					}
					*/
					if (posttimenode) {
						var slink = doc.createElement("A");
						slink.href = "http://forums.somethingawful.com/showthread.php?action=showpost&postid="+postid;
						slink.title = "Show Single Post";
						slink.appendChild( doc.createTextNode("1") );
						posttimenode.parentNode.insertBefore(slink, posttimenode);
						posttimenode.parentNode.insertBefore(doc.createTextNode(" "), posttimenode);
					}
					if (posttimenode && persistObject.toggle_insertPostLastMarkLink ) {
						var plink = doc.createElement("A");
						plink.href = "javascript:void('lr',"+postid+");";
						plink.title = "Set \"Last Read\" post in this thread to this post";
						plink.threadid = threadid;
						plink.postid = postid;
						plink.postdt = postdtvalue;
						plink.parentpost = resarray[x];
						plink.onclick = SALR_ChangeLastReadOnThread;
						plink.appendChild( doc.createTextNode("<") );
						doc.postlinks[doc.postlinks.length] = plink;
						posttimenode.parentNode.insertBefore(plink, posttimenode);
						posttimenode.parentNode.insertBefore(doc.createTextNode(" "), posttimenode);
					}
				}
			}
			//alert("l inserted");

			/*
			var postpane = selectSingleNode(doc, thisel, "TBODY[1]/TR[1]/TD[2]");

			if (persistObject.toggle_removeTargetNewFromTorrentLinks) {
			var tlinks = selectNodes(doc, postpane, "//A[contains(@href,'download.php?info_hash=')]");
			for (var i=0; i<tlinks.length; i++) {
			tlinks[i].target = "";
			}
			}
			*/
		}
	} // End of main post loop

	if (needCssInsert) {
		var csstxt = SALR_MakeShowThreadCSS(doc);
		var sel = doc.createElement("style");
		sel.type = "text/css";
		sel.innerHTML = csstxt;
		doc.getElementsByTagName('head')[0].appendChild(sel);
	}
	if (needUpdate && !persistObject.toggle_scrollPostEnable) {
		UpdateLPDateTime(updateTo, threadid, updateLastPostID);
	}

	if (persistObject.toggle_useQuickQuote) {
		//var replybuttons = selectNodes(doc, doc.body, "//A[contains(@href,'newreply.php')]/IMG[@alt='Post A Reply'][contains(@src,'forum-reply')]");
		//var replybutton = selectSingleNode(doc, doc.body,
		//        "TABLE/TBODY[1]/TR[1]/TD[2]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[1]/TD[2]/DIV[1]/A[2][contains(@href,'newreply.php')]/IMG[@alt='Post A Reply'][contains(@src,'forum-reply')]"
		//);
		// XXX: // to / when fonts are closed
		var replybutton = selectSingleNode(doc, doc.getElementById("container"), "DIV[@class='threadbar top']/UL[@class='postbuttons']//LI//A/IMG[contains(@src,'reply')]");
		if (replybutton) {
			makeQuickReplyButton(threadid, doc, replybutton, inBYOB);
		}

		var postbuttons = selectNodes(doc, doc.body, "//IMG[@alt='Post']");
		if (postbuttons.length) {
			for (var uiego = 0; uiego < postbuttons.length; uiego++) {
				makeQuickPostButton(threadid, doc, postbuttons[uiego]);
			}
		}

		//replybutton = selectSingleNode(doc, doc.body,
		//    "TABLE/TBODY[1]/TR[1]/TD[2]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[1]/TD[2]/TABLE[1]/TBODY[1]/TR[1]/TD[4]/A[1][contains(@href,'newreply.php')]/IMG[@alt='Post A Reply'][contains(@src,'forum-reply')]"
		//);
		replybutton = selectSingleNode(doc, doc.getElementById("container"), "DIV[@class='threadbar bottom']/UL[@class='postbuttons']//LI//A/IMG[contains(@src,'reply')]");
		if (replybutton) {


			makeQuickReplyButton(threadid, doc, replybutton, inBYOB);
		}
	}

	/*
	if (persistObject.toggle_thumbnailQuotedImagesInThreads) {
	var qimages = selectNodes(doc, doc.body, "//BLOCKQUOTE//IMG");
	for (var i=0; i<qimages.length; i++) {
	setupThumbnailImage(qimages[i],true,false);
	}
	}

	if (persistObject.toggle_removeTargetNewFromTorrentLinks) {
	var tlinks = selectNodes(doc, doc.body, "//A[contains(@href,'download.php?info_hash=')]");
	for (var i=0; i<tlinks.length; i++) {
	tlinks[i].target = "";
	}
	}
	*/

	function VideoEmbedder() {

		this.VIDEO_WIDTH = 450;
		this.VIDEO_HEIGHT = 370;
		this.embedder = this;

		this.processRemoveLink = function(e, linkNode, embedEl) {
			var targetEl = e.target;
			embedEl.parentNode.insertBefore(linkNode, embedEl);
			embedEl.parentNode.removeChild(embedEl);
			targetEl.parentNode.removeChild(targetEl);
			e.preventDefault();
			return false;
		}

		this.insertRemoveLink = function(linkNode, embedEl) {
			
			embedder = this.embedder;
			var aEl = document.createElement("A");
			aEl.href = document.location.href;
			aEl.appendChild(document.createTextNode("[hide]"));
			aEl.addEventListener('click', function(e) { embedder.processRemoveLink(e, linkNode, embedEl); }, false);
			embedEl.parentNode.insertBefore(aEl, embedEl);
		}

		this.vidClick = function(e, linkNode, videoId, isGoogle) {

			//thanks Cuddly Dan - http://forums.somethingawful.com/showthread.php?threadid=2397868&perpage=40&pagenumber=2#post325043505
			//this iterates through the parents of the link to get the actual A, used typically if the link is an image
			while(linkNode.tagName != "A" && typeof linkNode.parentNode != 'undefined') linkNode = linkNode.parentNode;
					
			var embedEl = document.createElement("EMBED");
			embedEl.setAttribute('width', this.VIDEO_WIDTH);
			embedEl.setAttribute('height', this.VIDEO_HEIGHT);
			embedEl.setAttribute('type', "application/x-shockwave-flash");
			if(isGoogle) {
				embedEl.setAttribute('flashvars', '');
				embedEl.setAttribute('src', 'http://video.google.com/googleplayer.swf?docId=' + videoId + '&hl=en');
			} else {
				embedEl.setAttribute('quality',"high");
				embedEl.setAttribute('bgcolor',"#FFFFFF");
				embedEl.setAttribute('wmode', "transparent");
				embedEl.setAttribute('src', "http://www.youtube.com/v/" + videoId);
			}

			linkNode.parentNode.insertBefore(embedEl, linkNode);
			this.insertRemoveLink(linkNode, embedEl);
			linkNode.parentNode.removeChild(linkNode);

			e.preventDefault();

			return;

			//<embed src="http://www.youtube.com/v/57NNvWJtFf4" wmode="transparent" type="application/x-shockwave-flash" bgcolor="#FFFFFF" quality="high" height="370" width="450">
			//<EMBED src="http://www.youtube.com/v/57NNvWJtFf4" wmode="transparent" bgcolor="#FFFFFF" quality="high" type="application/x-shockwave-flash" height="370" width="450">
			
		}

		this.prepareVideoPlayer = function(linkNode, videoId, isGoogle) {
			embedder = this.embedder;	
			linkNode.style.backgroundColor = "#ffcccc !important";
			linkNode.vidid = videoId;
			linkNode.addEventListener('click', function(e) { embedder.vidClick(e, e.target, videoId, isGoogle); }, false);
		}

		this._init = function(doc) {
						
			var links = selectNodes(doc, doc.body, '//a[starts-with(@href, "http")]');
			if(links.length) {
				for(var i=0; i < links.length; i++) {
					var thisLink = links[i];

					var href = thisLink.href;
					var hrefmatch = href.match(/^http\:\/\/(www\.)?youtube\.com\/watch\?v=([-_0-9a-zA-Z]+)/);
					if (hrefmatch) {
						var vidid = hrefmatch[2];
						this.prepareVideoPlayer(thisLink, vidid, false);
					} else {
						var ghrefmatch = href.match(/^http\:\/\/video\.google\.com\/videoplay\?docid=([-0-9]+)/);
						if (ghrefmatch) {
							var gvidid = ghrefmatch[1];
							this.prepareVideoPlayer(thisLink, gvidid, true);
						}
					}
				}
			}
		}
	}
	
	var ve = new VideoEmbedder();
	//setTimeout("ve._init(doc);",5000);
	ve._init(doc);
	
	try {
		var isLastPage = SALR_SearchForThreadPages(doc, "thread");
		if (typeof(isLastPage)=="object" && isLastPage.res == true) {
			var pcount = ((isLastPage.num-1) * 40) + resarray.length - 1;
			//alert("looks like "+pcount+" posts up in this bitch");
			slurpIntoThreadCache(threadid);
			if ( cachedThreadEntry ) {
				cachedThreadEntry.setAttribute("lastreplyct", pcount);
			}
		}
	} catch (e) { }
	try { SALR_InsertThreadKeyboardNavigation(doc); } catch (e) { }

	reanchorThreadToLink(doc);

	doc.__salastread_loading = true;
	window.addEventListener("load", SALR_PageFinishedLoading, true);
	if (persistObject.toggle_scrollPostEnable)
	setTimeout(function () { SALR_CheckScrollPostPosition(doc); }, 1000);

	addInternalDebugLog("showthread.php handler, thread #"+threadid+", lpbefore="+lpbefore+", lpafter="+lpafter);
}

var specialDoc;

function SALR_PageFinishedLoading(e) {
	var doc = e.originalTarget;
	doc.__salastread_loading = false;
}

function SALR_CheckScrollPostPosition(doc) {
	if (doc.__salastread_processed) {
		var scrollpos = doc.defaultView.scrollY + doc.defaultView.innerHeight;
		var i;
		var a;
		for (i = 0; i < doc.postlinks.length; i++) {
			a = doc.postlinks[i];
			if (a.postid && (doc.__salastread_loading || !a.absolutepos))
			a.absolutepos = SALR_GetVerticalPos(a.parentpost);
			if (a.absolutepos && scrollpos > a.absolutepos) {
				SALR_SetNewLastReadIfLarger(a.threadid, a.postdt, a.postid);
			}
		}
		setTimeout(function () { SALR_CheckScrollPostPosition(doc); }, 5000);
	}
}

function SALR_SetNewLastReadIfLarger(threadid, postdt, postid) {
	slurpIntoThreadCache(threadid);
	if (cachedThreadEntry) {
		var lastdt = cachedThreadEntry.getBypassAttribute("lastpostdt");
		if (lastdt && postdt > lastdt) {
			cachedThreadEntry.setAttribute("lastpostdt", postdt);
			cachedThreadEntry.setAttribute("lastpostid", postid);
			//persistObject.SaveXML();
			var threaddetails = new Array();
			threaddetails['id'] = threadid;
			threaddetails['lastpostdt'] = postdt;
			threaddetails['lastpostid'] = postid;
			persistObject.SavePostDataSQL(threaddetails);
		}
	}
}

function SALR_GetVerticalPos(element) {
	//var x = 0;
	var y = 0;
	var p = element;
	while (p) {
		//x += p.offsetLeft;
		y += p.offsetTop;
		p = p.offsetParent;
	}
	return y;
}


function SALR_InsertThreadKeyboardNavigation(doc) {
	// XXX: temporarily disabled
	return;
	doc.onkeypress = function(e) {
		if (e.which==32)
		{
			var curTop = doc.body.scrollTop;
			setTimeout(function() { SALR_CheckForSpaceScroll(doc, curTop); }, 50);
		}
	}
}

function SALR_CheckForSpaceScroll(doc, oldTop) {
	var newTop = doc.body.scrollTop;
	if (oldTop==newTop) {
		var bclassmatch = doc.body.className.match(/salastread_thread_(\d+)/);
		if (bclassmatch) {
			var curPage = doc._SALR_curPage;
			var maxPages = doc._SALR_maxPages;
			var threadid = Number(bclassmatch[1]);
			if (maxPages>curPage) {
				doc.location = "http://forums.somethingawful.com/showthread.php?s=&threadid="+threadid+"&pagenumber="+(curPage+1);
				return;
			}
			slurpIntoThreadCache(threadid);
			if (cachedThreadEntry) {
				var postid = cachedThreadEntry.getBypassAttribute("lastpostid");
				if (postid)
				{
					var nurl = "http://forums.somethingawful.com/showthread.php?s=&postid="+postid+"#post"+postid;
					if (doc.location.href == nurl)
					doc.location.reload();
					else
					doc.location = nurl;
				}
			}
		}
	}
}

function SALR_DirectionalNavigate(doc, dir) {
	var forumid = doc.location.href.match(/forumid=[0-9]+/);
	var posticon = doc.location.href.match(/posticon=[0-9]+/);
	if (!posticon) posticon = "posticon=0";

	if (dir == "top") {
		var tforum = doc.__SALR_forumid;
		if (tforum)
		doc.location = "http://forums.somethingawful.com/forumdisplay.php?s=&forumid="+tforum;
		else
		doc.location = "http://forums.somethingawful.com/forumdisplay.php?s=&"+forumid+"&"+posticon;
	}
	else if (dir == "left") {
		var curPage = doc.__SALR_curPage;
		if (curPage > 1) {
			var threadid = doc.__SALR_threadid;
			if (threadid)
			doc.location = "http://forums.somethingawful.com/showthread.php?s=&threadid="+threadid+"&perpage=40&pagenumber="+(curPage-1);
			else
			doc.location = "http://forums.somethingawful.com/forumdisplay.php?"+forumid+"&daysprune=30&sortorder=desc&sortfield=lastpost&perpage=40&"+posticon+"&pagenumber="+(curPage-1);
		}
	}
	else if (dir == "right") {
		var curPage = doc.__SALR_curPage;
		var maxPage = doc.__SALR_maxPage;
		if (maxPage > curPage) {
			var threadid = doc.__SALR_threadid;
			if (threadid)
			doc.location = "http://forums.somethingawful.com/showthread.php?s=&threadid="+threadid+"&perpage=40&pagenumber="+(curPage+1);
			else
			doc.location = "http://forums.somethingawful.com/forumdisplay.php?"+forumid+"&daysprune=30&sortorder=desc&sortfield=lastpost&perpage=40&"+posticon+"&pagenumber="+(curPage+1);
		}
	}
}

function SALR_PageMouseUp(event) {
	var targ = event.target;
	var doc = targ.ownerDocument;
	if (targ && targ.SALR_isGestureElement==true) {
		doc.body.addEventListener('contextmenu', SALR_GestureContextMenu, false);
		SALR_DirectionalNavigate(doc, targ.SALR_dir);
		//alert("dir="+targ.SALR_dir);
	}

	var gn = doc.getElementById("salastread_gesturenavtop");
	if (gn) {
		var rx = function(dir) {
			var el = doc.getElementById("salastread_gesturenav"+dir);
			el.parentNode.removeChild(el);
		}
		rx("top");
		rx("left");
		rx("right");
		rx("bottom");
	}
}

function SALR_GestureContextMenu(event) {
	var targ = event.target;
	var doc = targ.ownerDocument;
	doc.body.removeEventListener('contextmenu', SALR_GestureContextMenu, false);
	if (event.preventDefault) {
		event.preventDefault();
	}
	return false;
}

function SALR_PageMouseDown(event) {
	var doc = event.target.ownerDocument;
	var gn = doc.getElementById("salastread_gesturenavtop");
	if (gn) {
		return;
	}
	if (event.button == persistObject.int_gestureButton && persistObject.toggle_gestureEnable) {
		var cx = function(dir, ofsy, ofsx) {
			var el = doc.createElement("IMG");
			el.SALR_dir = ""+dir;
			el.id = "salastread_gesturenav"+dir;
			el.className = "salastread_gesturenav";
			el.src = "chrome://salastread/content/gesturenav-"+dir+".png";
			el.style.left = ((event.clientX - 36) + (77 * ofsx)) + "px";
			el.style.top = ((event.clientY - 36) + (77 * ofsy)) + "px";
			doc.body.appendChild(el);
			el.SALR_isGestureElement = true;

			if (dir=="left" && (doc.__SALR_curPage <= 1 || !doc.__SALR_curPage)) {
				el.className += " disab";
			}
			else if (dir=="right" && (doc.__SALR_maxPage <= doc.__SALR_curPage || !doc.__SALR_maxPage)) {
				el.className += " disab";
			}
		};
		cx("top", -1, 0);
		cx("left", 0, -1);
		cx("right", 0, 1);
		cx("bottom", 1, 0);

		if (!doc.__SALR_maxPage) {
			var ss = doc.createElement("link");
			ss.rel = "stylesheet";
			ss.href = "chrome://salastread/content/pagenavigator-content.css";
			doc.getElementsByTagName('head')[0].appendChild(ss);
		}
	}
}

function SALR_SearchForThreadPages(doc, type) {
	if ((!persistObject.toggle_enablePageNavigator && type=="thread") || ((!persistObject.toggle_enableForumNavigator && type=="forum")))
	return { res: false };

	doc.body.addEventListener('mousedown', SALR_PageMouseDown, false);
	doc.body.addEventListener('mouseup', SALR_PageMouseUp, false);
	//doc.body.addEventListener('contextmenu', SALR_GestureContextMenu, false);

	var rval = { res: true, num: 1 };
	//var pel = selectSingleNode(doc, doc.body, "TABLE/TBODY/TR/TD/TABLE[1]/TBODY/TR/TD/DIV[@class='mainbodytext']/B[1]/A[@class='pagenumber']");
	var pel = selectSingleNode(doc, doc.getElementById("container"), "DIV[@class='pages bottom']/B/A[@class='pagenumber']");
	if (pel) {
		//alert("found pel");
		var turl = pel.href;
		var boldel = pel.parentNode;
		pel = pel.parentNode.parentNode;
		var peltext = pel.innerHTML;
		var pcountmatch = peltext.match(/\((\d+)\):/);
		if (pcountmatch) {
			var maxPages = Number(pcountmatch[1]);
			//alert("I found "+maxPages+" pages.");

			for (var i=0; i<boldel.childNodes.length; i++) {
				var thisChild = boldel.childNodes[i];
				if (thisChild.nodeName=="#text") {
					var nmatch = thisChild.nodeValue.match(/(\d+)/);
					if (nmatch) {
						var curPage = Number(nmatch[1]);
						//alert("current page is "+nmatch[1]);

						var navDiv = doc.createElement("DIV");
						navDiv.className = "salastread_pagenavigator";
						//navDiv.style.position = "fixed";
						//navDiv.style.right = "0px";
						//navDiv.style.bottom = "0px";
						//navDiv.style.backgroundColor = "#ddd";
						//navDiv.style.padding = "4px 4px 4px 4px";

						var firstBtn = doc.createElement("IMG");
						firstBtn.src = "chrome://salastread/content/nav-firstpage.png";
						firstBtn.title = "Go to First Page";
						//firstBtn.appendChild(doc.createTextNode("<<"));
						//firstBtn.appendChild(firstPageImg);
						if (curPage==1) {
							//firstBtn.disabled = true;
							firstBtn.className = "disab";
						} else {
							firstBtn.onclick = function() { doc.location = turl.replace(/pagenumber=(\d+)/, "pagenumber=1"); };
						}

						var prevBtn = doc.createElement("IMG");
						prevBtn.src = "chrome://salastread/content/nav-prevpage.png";
						prevBtn.title = "Go to Previous Page";
						if (curPage==1) {
							//prevBtn.disabled = true;
							prevBtn.className = "disab";
						} else {
							prevBtn.onclick = function() { doc.location = turl.replace(/pagenumber=(\d+)/, "pagenumber="+(curPage-1)); };
						}

						doc.__SALR_curPage = curPage;
						doc.__SALR_maxPage = maxPages;

						var pageSel = doc.createElement("SELECT");
						pageSel.size = 1;
						for (var pp=1; pp<=maxPages; pp++)
						{
							var topt = doc.createElement("OPTION");
							topt.appendChild(doc.createTextNode(pp));
							if (pp==curPage) topt.selected = true;
							pageSel.appendChild(topt);
						}
						pageSel.onchange = function() { doc.location = turl.replace(/pagenumber=(\d+)/, "pagenumber="+(Number(pageSel.selectedIndex)+1)); };

						var nextBtn = doc.createElement("IMG");
						nextBtn.src = "chrome://salastread/content/nav-nextpage.png";
						nextBtn.title = "Go to Next Page";
						if (curPage==maxPages) {
							//nextBtn.disabled = true;
							nextBtn.className = "disab";
							rval.res = true;
							rval.num = curPage;
						} else {
							nextBtn.onclick = function() { doc.location = turl.replace(/pagenumber=(\d+)/, "pagenumber="+(curPage+1)); };
						}

						var lastBtn = doc.createElement("IMG");
						lastBtn.src = "chrome://salastread/content/nav-lastpage.png";
						lastBtn.title = "Go to Last Page";
						if (curPage==maxPages) {
							//lastBtn.disabled = true;
							lastBtn.className = "disab";
						} else {
							lastBtn.onclick = function() { doc.location = turl.replace(/pagenumber=(\d+)/, "pagenumber="+maxPages); };
						}

						navDiv.appendChild(firstBtn);
						navDiv.appendChild(prevBtn);
						navDiv.appendChild(pageSel);
						navDiv.appendChild(nextBtn);
						navDiv.appendChild(lastBtn);
						doc.body.appendChild(navDiv);

						var ss = doc.createElement("link");
						ss.rel = "stylesheet";
						ss.href = "chrome://salastread/content/pagenavigator-content.css";
						doc.getElementsByTagName('head')[0].appendChild(ss);

						doc._SALR_curPage = curPage;
						doc._SALR_maxPages = maxPages;

						break;
					}
				}
			}
		}
	}
	return rval;
}

var modCheckCache = null;

function SALR_IsModerator(userid, forumid) {
	if ( persistObject.forumListXml ) {
		var mList = null;
		if ( modCheckCache && modCheckCache[0]==forumid ) {
			mList = modCheckCache[1];
		} else {
			var forumNode = selectSingleNode( persistObject.forumListXml, persistObject.forumListXml, "//forum[@id='"+forumid+"']");
			if ( forumNode && forumNode.hasAttribute("mods") ) {
				mList = forumNode.getAttribute("mods").split(",");
			}
			if ( forumNode && forumNode.hasAttribute("modnames") ) {
				var mnList = forumNode.getAttribute("modnames").split(",");
				for (var i=0; i<mnList.length; i++) {
					mList.push(mnList[i]);
				}
			}
			modCheckCache = new Array(2);
			modCheckCache[0] = forumid;
			modCheckCache[1] = mList;
		}
		if ( mList ) {
			for (var i=0; i<mList.length; i++) {
				if (mList[i]==userid) {
					return true;
				}
			}
		}
	}
	return false;
}

function SALR_ChangeLastReadOnThread(e) {
	slurpIntoThreadCache(e.originalTarget.threadid);
	if (cachedThreadEntry) {
		cachedThreadEntry.setAttribute("lastpostdt", e.originalTarget.postdt);
		cachedThreadEntry.setAttribute("lastpostid", e.originalTarget.postid);
		//persistObject.SaveXML();
		var threaddetails = new Array();
		threaddetails['id'] = threadid;
		threaddetails['lastpostdt'] = e.originalTarget.postdt;
		threaddetails['lastpostid'] = e.originalTarget.postid;
		persistObject.SavePostDataSQL(threaddetails);

		var doc = e.originalTarget.ownerDocument;
		var notel = doc.createElement("DIV");
		notel.appendChild(doc.createTextNode("Last Post reset to this post."));
		notel.style.position = "absolute";
		notel.style.border = "1px solid black";
		notel.style.backgroundColor = "yellow";
		notel.style.color = "black";
		notel.style.padding = "2px 2px 2px 2px";
		notel.style.fontFamily = "Tahoma, Arial, Helvetica, sans-serif";
		notel.style.fontSize = "small";
		var lef = 0;
		var top = 0;
		var tel = e.originalTarget;
		while (tel) {
			lef += tel.offsetLeft;
			top += tel.offsetTop;
			tel = tel.offsetParent;
		}
		notel.style.top = (top + e.originalTarget.offsetHeight) + "px";
		notel.style.left = lef + "px";
		notel.opacity = 100;
		doc.body.appendChild(notel);
		setTimeout( function() { SALR_NoteFade(notel); }, 1000 );
	}
}

function SALR_NoteFade(targetEl) {
	targetEl.opacity -= 5;
	targetEl.style.MozOpacity = (targetEl.opacity / 100);
	if (targetEl.opacity > 5) {
		setTimeout( function() { SALR_NoteFade(targetEl); }, 10 );
	} else {
		targetEl.parentNode.removeChild(targetEl);
	}
}

function makeQuickReplyButton(threadid,doc,replybutton, inBYOB) {


	replybutton.style.width = "12px !important";
	replybutton.style.height = "20px !important";
	if(inBYOB){
		replybutton.src = "chrome://salastread/content/byobarrow.gif";
	}else{
		replybutton.src = "chrome://salastread/content/button-normalreply.gif";
	}
	replybutton.alt = "Normal Reply";

	var newreply = doc.createElement("IMG");
	if(inBYOB){
		newreply.src = "chrome://salastread/content/byob-qreply.gif";
	}else{
		newreply.src = "chrome://salastread/content/button-quickreply.gif";
	}
	newreply.alt = "Quick Reply";
	newreply.border = "0"
	newreply.style.cursor = "pointer";
	newreply.SALR_threadid = threadid;
	attachQuickQuoteHandler(threadid,doc,newreply,"",0);
	replybutton.parentNode.parentNode.insertBefore(newreply, replybutton.parentNode);
}

function makeQuickPostButton(threadid,doc,replybutton) {
	var forumid = replybutton.parentNode.href.match(/forumid=[0-9]+/);
	if (forumid.length) forumid = forumid[0].split(/=/);
	if (forumid.length) forumid = forumid[1];
	else return;

	replybutton.style.width = "12px !important";
	replybutton.style.height = "20px !important";
	if(forumid== 174){
		replybutton.src = "chrome://salastread/content/byobarrow.gif";
	}else{
		replybutton.src = "chrome://salastread/content/button-normalpost.gif";
	}
	replybutton.alt = "Normal Post";

	var newreply = doc.createElement("IMG");
	if(forumid== 174){
		newreply.src = "chrome://salastread/content/byob-qpost.gif";
	}else{
		newreply.src = "chrome://salastread/content/button-quickpost.gif";
	}
	newreply.alt = "Quick Post";
	newreply.border = "0"
	newreply.style.cursor = "pointer";
	newreply.SALR_threadid = undefined;
	newreply.SALR_forumid = forumid;
	attachQuickQuoteHandler(undefined,doc,newreply,"",0);
	replybutton.parentNode.parentNode.insertBefore(newreply, replybutton.parentNode);
}

function setupThumbnailImage(img,isquoted,istti) {
	img.__fullsize = false;
	img.__salastread_isquoted = isquoted;
	img.__salastread_texttoimage = istti;
	setImageThumbnailSize(img,false);
	if ( !img.__salastread_resizeattached==true ) {
		img.addEventListener("resize", setImageThumbnailSizeNonToggle, true);
		img.addEventListener("load", setImageThumbnailSizeNonToggleL, true);
		img.addEventListener("click", setImageThumbnailSizeToggle, true);
		//img.addEventListener("resize", function() { setImageThumbnailSize(img,false); }, true);
		//img.addEventListener("load", function() { setImageThumbnailSize(img,false); }, true);
		//img.addEventListener("click", function() { setImageThumbnailSize(img,true); }, true);
		img.__salastread_resizeattached = true;
	}
}

var imgresize_recurseprotect = 0;

function setImageThumbnailSizeNonToggleL(evt) {
	var img = evt.currentTarget;
	//alert("load "+img);
	setImageThumbnailSize(img, false);
}

function setImageThumbnailSizeNonToggle(evt) {
	var img = evt.originalTarget;
	setImageThumbnailSize(img, false);
}

function setImageThumbnailSizeToggle(evt) {
	var img = evt.originalTarget;
	setImageThumbnailSize(img, true);
}

function setImageThumbnailSize(img,fullsizetoggle) {
	if (imgresize_recurseprotect==0) {
		imgresize_recurseprotect = 1;
		if (fullsizetoggle) {
			img.__fullsize = !img.__fullsize;
		}
		var maxwidth = 150;
		var widthonly = 0;
		if ( img.__salastread_texttoimage==true && img.__salastread_isquoted==false ) {
			maxwidth = 600;
			widthonly = 1;
		}
		var scalepct = maxwidth/img.naturalWidth;
		if ( widthonly!=1 && maxwidth/img.naturalHeight < scalepct ) {
			scalepct = maxwidth/img.naturalHeight;
		}
		if (scalepct < 1) {
			if (img.__fullsize==true) {
				scalepct = 1;
			}
			img.style.width = Math.floor( img.naturalWidth * scalepct ) + "px";
			img.style.height = Math.floor( img.naturalHeight * scalepct ) + "px";
		}
		imgresize_recurseprotect = 0;
	}
}

function reanchorThreadToLink(doc) {

	if ( persistObject.toggle_reanchorThreadOnLoad ) {

		var hashmatch = doc.location.href.match(/\#(.*)$/);
		if (hashmatch) {
			var anchorNode = selectNodes(doc, doc.body, "//table[@id='"+hashmatch[1]+"']")[0];
			if (anchorNode) {
				anchorNode.scrollIntoView(true);
			}
		}
	}
}

function SALR_runConfig(page) {
	//var doc = e.originalTarget;
	//doc.location = "chrome://salastread/content/configuration.html";
	var data = "";
	if (typeof(page)=="string") {
		data = page;
	}
	openDialog("chrome://salastread/content/pref.xul","_blank",
	"chrome,titlebar,modal,resizable", data);
}

function handleEditPost(e) {
	var doc = e.originalTarget;
	var submitbtn = selectNodes(doc, doc.body, "//INPUT[@type='submit'][@value='Save Changes']")[0];
	var tarea = selectNodes(doc, doc.body, "//TEXTAREA[@name='message']")[0];
	if (submitbtn && tarea) {
		submitbtn.addEventListener("click", function() { parsePLTagsInEdit(tarea); }, true);
		submitbtn.style.backgroundColor = persistObject.color_postedInThreadRe;
	}
}

var salastread_needRegReplyFill = false;

function setRegReplyFillOn() {
	salastread_needRegReplyFill = true;
}

function handleNewReply(e) {
	var doc = e.originalTarget;
	var threadlink = selectSingleNode(doc, doc.body, "DIV[contains(@id, 'container')]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/SPAN[1]/B/A[contains(@href,'showthread.php')][contains(@href,'threadid=')]");
	if (threadlink) {
		var tlmatch = threadlink.href.match( /threadid=(\d+)/ );
		if ( tlmatch ) {
			var threadid = tlmatch[1];
			if ( salastread_needRegReplyFill ) {
				var msgEl = selectSingleNode(doc, doc.body, "//TEXTAREA[@name='message']");
				if (msgEl) {
					msgEl.value = salastread_savedQuickReply;
				}
				salastread_needRegReplyFill = false;
			}
			var postbtn = selectNodes(doc, doc.body, "//FORM[@name='vbform'][contains(@action,'newreply.php')]//INPUT[@type='submit'][@name='submit']")[0];
			if (postbtn) {
				postbtn.addEventListener("click", function() { markThreadReplied(persistObject, threadid); }, true);
				postbtn.style.backgroundColor = persistObject.color_postedInThreadRe;
			}
		}
	} else {
		if (salastread_savedQuickReply!="") {
			var forgeCheck = selectSingleNode(doc, doc.body, "TABLE/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[2]/TD[1]/FONT[contains(text(),'have been forged')]");
			if (forgeCheck) {
				persistObject.__cachedFormKey = "";
				var reqMsg = doc.createElement("P");
				reqMsg.style.fontFamily = "Verdana, Arial, Helvetica";
				reqMsg.style.fontSize = "80%";
				reqMsg.style.backgroundColor = "#fcfd99";
				reqMsg.style.border = "1px solid black";
				reqMsg.style.padding = "2px 2px 2px 2px";
				reqMsg.appendChild(
				doc.createTextNode("Message from SA Last Read: " +
				"Quick Reply appears to have worked incorrectly. To open "+
				"your reply in a regular forum reply page, click ")
				);
				var regReplyLink = doc.createElement("A");
				regReplyLink.onclick = setRegReplyFillOn;
				regReplyLink.href = "http://forums.somethingawful.com/newreply.php?s=&action=newreply&threadid=" +
				salastread_savedQuickReplyThreadId;
				regReplyLink.appendChild(doc.createTextNode("here."));
				reqMsg.appendChild(regReplyLink);
				forgeCheck.parentNode.insertBefore(reqMsg, forgeCheck);
			} else {
				salastread_savedQuickReply = "";
				salastread_savedQuickReplyThreadId = "";
			}
		}
	}
}

function markThreadReplied(pobj, threadid) {
	var xmlDoc = pobj.xmlDoc;
	var threads = selectNodes(xmlDoc, xmlDoc, "/salastread/thread[@id='"+threadid+"']");
	for (var i=0; i<threads.length; i++) {
		threads[i].setAttribute("posted","1");
	}
	invalidateThreadCache();
	//pobj.SaveXML();
	var threaddetails = new Array();
	threaddetails['id'] = threadid;
	threaddetails['posted'] = 1;
	persistObject.SavePostDataSQL(threaddetails);
}

function handleConfigLinkInsertion(e) {
	var doc = e.originalTarget;
	var usercpnode = selectSingleNode(doc, doc.body, "//A[@class='pagenumbersmall'][contains(@href,'usercp.php?s=')]");
	if (usercpnode) {
		var sep = doc.createTextNode(" - ");
		var newlink = doc.createElement("A");
		newlink.appendChild( doc.createTextNode("Configure Last Read Extension") );
		usercpnode.parentNode.insertBefore(newlink, usercpnode.nextSibling);
		usercpnode.parentNode.insertBefore(sep, newlink);
		newlink.href = "#";
		//newlink.href = "chrome://salastread/content/configuration.html";
		newlink.className = "pagenumbersmall";
		//newlink.onclick = function() { runConfig(e); };
		newlink.addEventListener("click", SALR_runConfig, true);
		//newlink.onclick = runConfig;
		return 1;
	} else {
		return 0;
	}
}

function salastread_addUpdateIcon(doc) {
	if ( persistObject._updateURL != "" ) {
		var updlink = doc.createElement("A");
		var updicon = doc.createElement("IMG");
		updlink.href = persistObject._updateURL;
		if ( persistObject._killed==true ) {
			updicon.src = "chrome://salastread/content/killedicon.png";
			updicon.title = "SA Last Read Update REQUIRED";
		} else {
			updicon.src = "chrome://salastread/content/updateicon.png";
			updicon.title = "SA Last Read Update Available";
		}
		updicon.style.width = "35px";
		updicon.style.height = "33px";
		updicon.style.border = "none";
		updlink.appendChild(updicon);
		updlink.style.display = "block";
		updlink.style.position = "fixed";
		updlink.style.right = "5px";
		updlink.style.bottom = "5px";
		doc.body.appendChild(updlink);
	}
}

function handleBodyClassing(e) {
	var doc = e.originalTarget;
	var docbody = doc.body;
	var addclass = " somethingawfulforum";
	var phmatch = doc.location.href.match( /\/([^\/]*)\.php/ );
	if (phmatch) {
		addclass += " somethingawfulforum_"+phmatch[1]+"_php";
	}
	docbody.className += addclass;
}

/*
function __TEST__hookupTitleChanged() {
document.getElementById("content").addEventListener("DOMTitleChanged", __TEST__salastread_titleChanged, false);
}

var checkForCopyrightFailCount = 0;

function __TEST__salastread_titleChanged(event) {
var loc = event.target.location;
if ( loc.href.match(/^http:\/\/forums\.somethingawful\.com\//i) ) {
var fakee = {
originalTarget: event.target
};
//setTimeout( function() { salastread_windowOnLoad(fakee); }, 50 );
checkForCopyrightFailCount = 0;
setTimeout( function() { __TEST__docloaded(fakee); }, 50 );
}
}

function __TEST__docloaded(e) {
var doc = e.originalTarget;
try {
// copyright notice at bottom of page is the only <p> in the main body of a forum page
//var copyrightnotice = selectNodes(doc, doc.body, "P/FONT")[0];

var commentnodes = selectNodes(doc, doc.body, "child::comment()");
var count=0;
for (var i=0; i<commentnodes.length; i++) {
var cn = commentnodes[i];
if (cn.nodeValue.match(/End ad\-free/)) {
count++;
}
}
//if (count>0) { alert("count = "+count); return; }
if (count==2) {
salastread_windowOnLoad(e);
return;
}
}
catch (err) {
}
checkForCopyrightFailCount++;
if (checkForCopyrightFailCount < 5) {
setTimeout( function() { __TEST__docloaded(e); }, 50 );
}
else if (checkForCopyrightFailCount < 10) {
setTimeout( function() { __TEST__docloaded(e); }, 250 );
}
else {
//alert("salastread: t-t-t-t-t-t-TOTAL FAILURE!");
}
}
*/

function salastread_hidePageHeader(doc) {
	var hiddenElements = new Array();
	var hideEl = function(id) {
		var el;
		if (typeof id == "string") {
			el = doc.getElementById(id);
		} else {
			el = id;
		}
		if (el) {
			el.SALR_display = el.style.display;
			el.style.display = "none";
			hiddenElements.push(el);
		}
	}

	hideEl("globalmenu");
	hideEl("searchboxes");
	hideEl("navigation");
	var nav = doc.getElementById("navigation");
	if (nav) {
		nav = nav.nextSibling;
		if (nav && nav.nodeName != "DIV") {
			nav = nav.nextSibling;
		}
		if (nav && selectSingleNode(doc, nav, "A[@target='_new']/IMG")) {
			hideEl(nav);
		}
	}
	hideEl("copyright");
	var copyright = doc.getElementById("copyright");
	if (copyright) {
		if (copyright) copyright = copyright.previousSibling;
		if (copyright && copyright.nodeName != "DIV") copyright = copyright.previousSibling;
		if (copyright && selectSingleNode(doc, copyright, "A[@target='_new']/IMG")) {
			hideEl(copyright);
		}
	}

	if (hiddenElements.length > 0) {
		var togLink = doc.createElement("DIV");
		togLink.className = "salastread_showhideheaderbutton";
		togLink.appendChild(doc.createTextNode("[Show Header/Footer]"));
		togLink.onclick = function() {
			for (var i=0; i<hiddenElements.length; i++) {
				var tel = hiddenElements[i];
				tel.style.display = tel.SALR_display;
			}
			togLink.style.display = "none";
			return false;
		};
		doc.body.appendChild(togLink);

		var lr = doc.createElement("link");
		lr.rel = "stylesheet";
		lr.type = "text/css";
		lr.href = "chrome://salastread/content/hideshowheaderbutton.css";
		doc.getElementsByTagName('head')[0].appendChild(lr);
	}
}

function salastread_hidePageHeader_OLD(doc) {
	var showToggleLink = false;
	var oldDisplay = new Array();
	var showElements = new Array();
	var searchTable = selectSingleNode(doc, doc.body, "TABLE[1]");
	if (searchTable && searchTable.innerHTML.match(/Search Google/)) {
		oldDisplay.push(searchTable.style.display);
		searchTable.style.display = "none";
		showToggleLink = true;
		showElements.push(searchTable);
	}
	//var linksTable = selectSingleNode(doc, doc.body, "TABLE[2]");
	var linksTable = selectSingleNode(doc, doc.body, "DIV[1][@id='globalthing']");
	//if (linksTable && linksTable.innerHTML.match(/Something Awful Website/)) {
	if (linksTable) {
		oldDisplay.push(linksTable.style.display);
		linksTable.style.display = "none";
		showToggleLink = true;
		showElements.push(linksTable);
	}
	var adDiv = selectSingleNode(doc, doc.body, "DIV[1]");
	if (adDiv && adDiv.innerHTML.match(/zipa.com/)) {
		oldDisplay.push(adDiv.style.display);
		adDiv.style.display = "none";
		showToggleLink = true;
		showElements.push(adDiv);
	}

	var centerEls = selectNodes(doc, doc.body, "CENTER");
	for (var cn=centerEls.length-1; cn>=0; cn--) {
		if (centerEls[cn].innerHTML.match(/bannerads/)) {
			oldDisplay.push(centerEls[cn].style.display);
			centerEls[cn].style.display = "none";
			showToggleLink = true;
			showElements.push(centerEls[cn]);
			cn = 0;
		}
	}
	var divEls = selectNodes(doc, doc.body, "DIV");
	for (var dn=divEls.length-1; dn>=0; dn--) {
		var dstr = divEls[dn].innerHTML;
		if (dstr.match(/Jelsoft Enterprises/) && !dstr.match(/Comedy Gas Chamber/)) {
			oldDisplay.push(divEls[dn].style.display);
			divEls[dn].style.display = "none";
			showToggleLink = true;
			showElements.push(divEls[dn]);
			dn = 0;
		}
	}


	if (showToggleLink) {
		var togLink = doc.createElement("DIV");
		togLink.appendChild(doc.createTextNode("[Show Header/Footer]"));
		togLink.style.position = "absolute";
		togLink.style.top = "0px";
		togLink.style.right = "0px";
		togLink.style.fontFamily = "Tahoma, Arial, Helvetica, sans-serif";
		togLink.style.fontSize = "8.5pt";
		togLink.style.fontWeight = "bold";
		togLink.style.padding = "2px";
		togLink.style.margin = "3px";
		togLink.style.display = "block";
		togLink.style.cursor = "pointer";
		togLink.style.border = "2px outset rgb(0,102,153)";
		togLink.style.backgroundColor = "rgb(0,102,153)";
		togLink.style.color = "rgb(255,255,255)";
		togLink.style.zIndex = "1000";
		togLink.onclick = function() {
			for (var i=0; i<showElements.length; i++) {
				showElements[i].style.display = oldDisplay[i];
			}
			togLink.style.display = "none";
			return false;
		};
		doc.body.appendChild(togLink);
	}
}

function SALR_ParamsToUrl(params) {
	var res = "";
	for (var key in params) {
		if (key.indexOf("salr_")==0) {
			res += "&" + escape(key) + "=" + escape(params[key]);
		}
	}
	return res;
}

var SALR_ProfileUserName;

function SALR_HandleProfileInsertion(e) {
	try
	{
		var doc = e.originalTarget;
		var location = doc.location;

		var params = new Object();

		var qstring = location.search;
		if (qstring.substr(0,1)=="?")
		qstring = qstring.substr(1);
		var qsplit = qstring.split("&");
		for (var qn=0; qn<qsplit.length; qn++) {
			var qparams = qsplit[qn].split("=");
			var qname = unescape(qparams[0]);
			var qvalue = unescape(qparams[1]);
			params[qname] = qvalue;
		}

		var capImg = doc.getElementById("captcha");

		if ( capImg && params["salr_addprofilekey"] && params["action"]=="editprofile" ) {
			var ihtmlm = doc.body.innerHTML.match(/">User Control Panel For (.*?)<\/a>/);
         if (!ihtmlm) return;
         SALR_ProfileUserName = ihtmlm[1];
         setTimeout(function() {
            var data = new Object();
            data["captchaUrl"] = capImg.src;
            openDialog("chrome://salastread/content/profileEditConfirm.xul","_blank",
            "chrome,titlebar,modal,resizable", data);
            if (data["continue"]) {
            	var formtag = selectSingleNode(doc, doc.body, "//form[@action='member.php']");
            	var captext = selectSingleNode(doc, doc.body, "//input[@name='captcha']");
            	var f1 = selectSingleNode(doc, doc.body, "//input[@name='field1']");
            	if (formtag && captext && f1) {
            		f1.value = "SALR["+ params["salr_addprofilekey"] +"]";
            		formtag.action = "member.php?salr_profileinsertcontinue=true" + SALR_ParamsToUrl(params);
            		captext.value = data["captchaText"];
            		formtag.submit();
            	}
            }
		},1);
		return;
	}
	else if ( params["salr_profileinsertcontinue"]=="true" ) {
		if (doc.body.innerHTML.indexOf("hank you for")!=-1) {
			// Success!!
			alert("Profile successfully updated");
			if (params["salr_onsuccessurl"]) {
				var surl = params["salr_onsuccessurl"];
				if (surl.indexOf("?")!=-1)
				surl += "&";
				else
				surl += "?";
				surl += "salr_username=" + SALR_ProfileUserName;
				doc.location = surl;
			}
		} else {
			if (confirm("Your profile did not update correctly. (You may have entered an incorrect validation code.) "+
			"Press OK to try again.")) {
				doc.location = "http://forums.somethingawful.com/member.php?s=&action=editprofile"+SALR_ParamsToUrl(params);
			}
		}
	}
} catch (err) { }
}

function SALR_windowOnLoadMini(e) {
	var doc = e.originalTarget;
	var location = doc.location;
	try {
		if (doc.__salastread_processed) {
			if ( persistObject.toggle_reanchorThreadOnLoad ) {
				var samatch = location.href.match( /^http:\/\/forums?\.somethingawful\.com\//i );
				if (samatch) {
					if ( location.href.indexOf("showthread.php?") != -1 ) {
						reanchorThreadToLink(doc);
					}
				}
			}
			return;
		}
	}
	catch (ex) { }
}

var SALR_SilenceLoadErrors = false;
var firstLoad = true;
var loadCount = 0;

/*
*
*  onload Handler
*  This function is a clusterfuck of immense proportions.
*
*/
function salastread_windowOnLoad(e) {

	// This IF statement included to help debugging, change the pref value to disable without restarting FF
	if (Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPrefService).getBranch("extensions.salastread.").getBoolPref("disabled") == false) {

		//alert("e is "+e+"\ne.originalTarget.location.href is "+e.originalTarget.location.href);
		//if ( e.originalTarget == "[Object HTMLDocument]" ) {
		//   alert("originalTarget is " + e.originalTarget + "\ntypeof = "+typeof(e.originalTarget));
		//}
		//var doc = window._content.document;
		//SALR_UpdateStatusBarIcon();
		SALR_SilenceLoadErrors = false;

		var doc = e.originalTarget;
		var location = doc.location;
		try {
			if ( location && location.href && !doc.__salastread_processed ) {
				var samatch = location.href.match( /^http:\/\/forums?\.somethingawful\.com\//i );
				if (samatch) {
					salastread_addUpdateIcon(doc);
					// Moved below, where it should be
					//if (persistObject.toggle_removeHeaderAndFooter) {
					//   salastread_hidePageHeader(doc);
					//}
				}
			}
		} catch(ex) { }

		if ( persistObject._killed==true ) {
			if ( persistObject._killMessage!="" ) {
				alert( "SA Last Read Message:\n\n" + persistObject._killMessage );
			}
			persistObject._killMessage = "";
			return;
		}

		try {
			loadCount++;
			if (firstLoad) {
				firstLoad = false;
				if ( persistObject.toggle_showSAForumMenu && persistObject.forumListXml && persistObject.forumListXml != null ) {
					try { buildSAForumMenu(); } catch(xx) { alert("buildsaforummenu err:"+xx); };
				}
				// DOMContentLoaded test...
				//__TEST__hookupTitleChanged();
				document.getElementById("appcontent").addEventListener("DOMContentLoaded", salastread_windowOnLoad, false);
				document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", SALR_ContextMenuShowing, false);
			}
			if (loadCount==3) {
				if (needToShowChangeLog==true) {
					needToShowChangeLog = false;
					showChangelogWindow();
				}
				window.removeEventListener('load', salastread_windowOnLoad, true);
				window.addEventListener('load', SALR_windowOnLoadMini, true);
			}
			//var doc = e.originalTarget;
			//var location = doc.location;
			if (doc.__salastread_processed) {
				if ( persistObject.toggle_reanchorThreadOnLoad ) {
					var samatch = location.href.match( /^http:\/\/forums?\.somethingawful\.com\//i );
					if (samatch) {
						if ( location.href.indexOf("showthread.php?") != -1 ) {
							reanchorThreadToLink(doc);
						}
					}
				}
				return;
			}
			if ( location && location.href && !doc.__salastread_processed ) {
				var samatch = location.href.match( /^http:\/\/forums?\.somethingawful\.com\//i );
				if (samatch && doc.defaultView.getComputedStyle(doc.body,'').getPropertyValue('background-color')!="rgb(255, 153, 153)") {
					//            var newPageTimer = persistObject.TimeManager.GetStart();
					//            doc.__SALASTREAD_PAGETIMER = newPageTimer;
					//            thisWindowPageTimers.push(newPageTimer);
					// why the FUCK doesn't this work?
					//doc.addEventListener("unload", function() { alert("a"); doc.__SALASTREAD_PAGETIMER.Finalize(); }, true);
					var hresult = 0;
					if ( location.href.indexOf("forumdisplay.php?") != -1 ) {
						if (doc.getElementById('forum') != null) {
							// Only do if there is a list of posts
							hresult = handleForumDisplay(e);
							addInternalDebugLog("forumdisplay.php handler");
						}
					}
					else if ( location.href.indexOf("showthread.php?") != -1 ) {
						handleShowThread(e);
					}
					else if ( location.href.indexOf("newreply.php") != -1 ) {
						handleNewReply(e);
					}
					else if ( location.href.indexOf("editpost.php") != -1 ) {
						handleEditPost(e);
					}
					else if ( location.href.indexOf("member2.php") != -1 ||
					location.href.indexOf("usercp.php") != -1 ) {
						handleSubscriptions(e);
					}
					else if ( location.href.indexOf("member.php") != -1 &&
					location.href.indexOf("salr_") != -1 ) {
						SALR_HandleProfileInsertion(e);
					}
					var hcliresult = handleConfigLinkInsertion(e);
					handleBodyClassing(e);
					//salastread_addUpdateIcon(doc);
					doc.__salastread_processed = true;
					// XXX: The unload prevents FF 1.5 from using Quick Back Button.
					//      SALR needs to work with it, but this works to prevent trouble in the meantime.
					if (true) {
						var screl = doc.createElement("SCRIPT");
						screl.setAttribute("language","javascript");
						screl.setAttribute("src","chrome://salastread/content/pageunload.js");
						doc.getElementsByTagName('head')[0].appendChild(screl);
					}
					SALR_IncTimer();
					if ( persistObject.toggle_enableDebugMarkup ) {
						var dbg = doc.createElement("DIV");
						dbg.innerHTML = SALR_debugLog.join("<br>");
						doc.body.appendChild(dbg);
					}
					if ( persistObject.toggle_removePageTitlePrefix ) {
						var titlematch = doc.title.match( /^The Something Awful Forums \- (.*)$/ );
						if (titlematch) {
							doc.title = titlematch[1] + " - The Something Awful Forums";
						}
					}
					if (persistObject.toggle_removeHeaderAndFooter) {
						salastread_hidePageHeader(doc);
					}
					if (persistObject.toggle_props) {
						var ssel = doc.createElement("LINK");
						ssel.setAttribute('rel',"STYLESHEET");
						ssel.setAttribute('type',"text/css");
						ssel.setAttribute('href',"chrome://salastread/content/props.css");
						//ssel.setAttribute('href',"file://C|/Documents%20and%20Settings/Tim%20Fries/Desktop/SALastRead/src/jar/content/salastread/props.css");
						//ssel.setAttribute('href','data:text/css,body{background:red;}');
						doc.getElementsByTagName('head')[0].appendChild(ssel);
					}
					//} else {
					//   if ( location.href == "chrome://salastread/content/configuration.html" ) {
					//      doc.persistObject = persistObject;
					//   }
				}
			}
		}
		catch(ex) {
			if ( !e.runSilent || SALR_SilenceLoadErrors ) {
				if (typeof(ex)=="object")
				{
					var errstr = "";
					for ( var tn in ex ) {
						errstr += tn+": "+ex[tn]+"\n";
					}
					if (!persistObject || !persistObject.toggle_suppressErrors)
					alert("SALastRead application err: "+errstr);
				} else {
					if (!persistObject || !persistObject.toggle_suppressErrors)
					alert("SALastRead application err: "+ex);
				}
			} else {
				throw ex;
			}
		}
		//   cleanupLostPageTimers();

	}
}

function SALR_PageUnloadHandler() {
	alert("a");
}

function SALR_ContentUpdateCurrentBrowser() {
	//window.setTimeout( function() { SALR_UpdateStatusBarIcon(); }, 10 );
}

/*
function SALR_UpdateStatusBarIcon() {
var cont = document.getElementById("content");
try {
var doc = cont.mCurrentBrowser.contentDocument;
if ( doc && doc.location && doc.location.hostname && doc.location.hostname.match(/somethingawful\.com$/i) ) {
document.getElementById("somethingawful-button").style.display = "-moz-box";
} else {
document.getElementById("somethingawful-button").style.display = "none";
}
}
catch (ex) {
document.getElementById("somethingawful-button").style.display = "none";
}
}
*/

function SALR_ShowContextMenuItem(id) {
	var cacm = document.getElementById("contentAreaContextMenu");
	var mopt = document.getElementById("salastread-context-menu");
	var moptsep = document.getElementById("salastread-context-menuseparator");
	cacm.removeChild(mopt);
	cacm.removeChild(moptsep);
	if ( persistObject.toggle_contextMenuOnBottom ) {
		cacm.appendChild(moptsep);
		cacm.appendChild(mopt);
	} else {
		cacm.insertBefore( moptsep, cacm.firstChild );
		cacm.insertBefore( mopt, moptsep );
	}
	document.getElementById(id).style.display = "-moz-box";
	mopt.style.display = "-moz-box";
	moptsep.style.display = "-moz-box";
}

function SALR_HideContextMenuItems() {
	document.getElementById("salastread-context-menu").style.display = "none";
	document.getElementById("salastread-context-menuseparator").style.display = "none";
	var pu = document.getElementById("salastread-context-menupopup");
	for (var i=0; i<pu.childNodes.length; i++) {
		pu.childNodes[i].style.display = "none";
		pu.childNodes[i].data = "";
	}
}

function SALR_ContextMenuShowing(e) {
	if ( e.originalTarget == document.getElementById("contentAreaContextMenu") ) {
		SALR_HideContextMenuItems();
		try {
			var doc = document.getElementById("content").mCurrentBrowser.contentDocument;
			if ( doc.__salastread_processed == true ) {
				SALR_ContextVis_IgnoreThisThread(doc);
				SALR_ContextVis_StarThisThread(doc);
				//SALR_ContextVis_ThreadWatch(doc);
			}
		}
		catch (ex) {
		}
	}
}

function SALR_ContextVis_IgnoreThisThread(doc) {
	var target = gContextMenu.target;
	var threadid = null;
	while (target) {
		if (target.className) {
			var tidmatch = target.className.match(/salastread_thread_(\d+)/);
			if (tidmatch) {
				threadid = tidmatch[1];
				SALR_ShowContextMenuItem("salastread-context-ignorethread");
				document.getElementById("salastread-context-ignorethread").data = threadid;
				document.getElementById("salastread-context-ignorethread").lpdtvalue = target.lpdtvalue;
				document.getElementById("salastread-context-ignorethread").target = target;
				document.getElementById("salastread-context-ignorethread").label = "Ignore This Thread ("+threadid+")";
			}
		}
		target = target.parentNode;
	}
}

function SALR_ContextVis_StarThisThread(doc) {
	var target = gContextMenu.target;
	var threadid = null;
	while (target) {
		if (target.className) {
			var tidmatch = target.className.match(/salastread_thread_(\d+)/);
			if (tidmatch) {
				threadid = tidmatch[1];
				slurpIntoThreadCache(threadid);
				SALR_ShowContextMenuItem("salastread-context-starthread");
				document.getElementById("salastread-context-starthread").data = threadid;
				document.getElementById("salastread-context-starthread").lpdtvalue = target.lpdtvalue;
				document.getElementById("salastread-context-starthread").target = target;
				if ( cachedThreadEntry && cachedThreadEntry.getAttribute("star")=="1" ) {
					document.getElementById("salastread-context-starthread").label = "Unstar This Thread ("+threadid+")";
				} else {
					document.getElementById("salastread-context-starthread").label = "Star This Thread ("+threadid+")";
				}
			}
		}
		target = target.parentNode;
	}
}

function SALR_ContextVis_ThreadWatch(doc) {
	if ( doc.location.href.indexOf("showthread.php")!=-1 ) {
		var tidmatch = doc.location.href.match(/threadid=(\d+)/);
		if (tidmatch) {
			var threadid = tidmatch[1];
			SALR_ShowContextMenuItem("salastread-context-threadwatch");
			document.getElementById("salastread-context-threadwatch").data = threadid;
			document.getElementById("salastread-context-threadwatch").label = "ThreadWatch ("+threadid+")";
		}
	}
}

function SALR_StarThread() {
	var threadid = document.getElementById("salastread-context-starthread").data;
	var lpdtvalue = document.getElementById("salastread-context-starthread").lpdtvalue;
	var target = document.getElementById("salastread-context-starthread").target;
	if (threadid) {
		slurpIntoThreadCache(threadid);
		cachedThreadEntry.setAttribute("star", (cachedThreadEntry.getAttribute("star")=="1") ? "0" : "1");
		//persistObject.SaveXML();
		var threaddetails = new Array();
		threaddetails['id'] = threadid;
		threaddetails['star'] = cachedThreadEntry.getAttribute("star");
		persistObject.SavePostDataSQL(threaddetails);
		if ( target.ownerDocument.location.href.indexOf("showthread.php")==-1 ) {
			target.ownerDocument.location = target.ownerDocument.location;
		} else {
			var startext = cachedThreadEntry.getAttribute("star")=="0" ? "unstarred" : "starred";
			alert("This thread is now "+startext+".");
		}
	}
}

function SALR_IgnoreThread() {
	var threadid = document.getElementById("salastread-context-ignorethread").data;
	var lpdtvalue = document.getElementById("salastread-context-ignorethread").lpdtvalue;
	var target = document.getElementById("salastread-context-ignorethread").target;
	if (threadid) {
		if ( confirm("Are you sure you want to ignore thread #"+threadid+"?") ) {
			slurpIntoThreadCache(threadid);
			cachedThreadEntry.setAttribute("ignore", "1");
			if ( cachedThreadEntry.getBypassAttribute("lastpostdt")==0 ) {
				cachedThreadEntry.setAttribute("lastpostdt", GetCurrentLPDateTime());
				cachedThreadEntry.setAttribute("lastpostid", "1");
			}
			//persistObject.SaveXML();
			var threaddetails = new Array();
			threaddetails['id'] = threadid;
			threaddetails['ignore'] = 1;
			threaddetails['lastpostdt'] = GetCurrentLPDateTime();
			threaddetails['lastpostid'] = 1;
			persistObject.SavePostDataSQL(threaddetails);
			target.style.display = "none";
		}
	} else {
		alert("menu item with no threadid.");
	}
}

function SALR_ThreadWatch() {
	window.open("chrome://salastread/content/threadwatch/threadwatch.xul", "_blank",
	"chrome, centerscreen, titlebar, resizable");
}

function showChangelogWindow() {
	//window.open("chrome://salastread/content/changelog.xul?autopop=1", "changelog", "chrome,centerscreen,resizable,modal");
	var param = new Object();
	param["upgradeFromVersion"] = upgradeFromVersion;
	//window.open("chrome://salastread/content/changelog.xul?autopop=1", "changelog", "chrome,centerscreen,resizable", param);
	openDialog("chrome://salastread/content/newfeatures/newfeatures.xul", "SALR_newfeatures", "chrome,centerscreen,dialog=no", param);
}

var killcheckxmlhttp;

function saLastReadKillCheck() {
	persistObject._killChecked = true;
	if ( persistObject.toggle_dontCheckKillSwitch ) {
		return;
	}
	killcheckxmlhttp = new XMLHttpRequest();
	killcheckxmlhttp.open("GET","http://static.evercrest.com/www/images2/ext/sa/salastread-kill.xml",true);
	killcheckxmlhttp.onreadystatechange = function() {
		try {
			if (killcheckxmlhttp.readyState==2) {
				if (killcheckxmlhttp.status != 200) {
					//alert("aborting ks xml");
					killcheckxmlhttp.abort();
				}
			}
			else if (killcheckxmlhttp.readyState==4) {
				//alert("processing ks xml ("+killcheckxmlhttp.responseText+")...");
				var xdoc = killcheckxmlhttp.responseXML;
				if ( xdoc!=null ) {
					var xel = xdoc.documentElement;
					if ( xel!=null ) {
						var before = xel.getAttribute("before");
						if ( Number(before) > 1912 ) {
							persistObject._killed = true;
							persistObject._killMessage = "Please upgrade to a newer version of the SA Last Read extension.\n"+
							"The version you have installed is "+
							"out of date and has been disabled for this browser session.";
						}
						for (var x=0; x<xel.childNodes.length; x++) {
							var thischild = xel.childNodes[x];
							if (thischild.nodeName == "dev" ) {
								var currentver = thischild.getAttribute("current");
								var updateurl = thischild.getAttribute("url");
								if ( Number(currentver) > 1912 ) {
									persistObject._updateURL = updateurl;
								}
							}
						}
						//DELETEME -- Uncomment this to force a killed version
						//persistObject._killed = true;
						//persistObject._killMessage = "This should never be released.";
						return;
					}
				}
				//persistObject._killed = true;
				//persistObject._killMessage = "Failed to get kill switch XML.";
			}
		}
		catch (e) {
			//alert("SALastRead Kill Switch Check Error: "+e);
		}
	};
	killcheckxmlhttp.send(null);
}

try {
	persistObject = Components.classes["@evercrest.com/salastread/persist-object;1"]
	.createInstance(Components.interfaces.nsISupports);
	persistObject = persistObject.wrappedJSObject;
	if (!persistObject)
	throw "Failed to create persistObject.";

	SALR_CURRENT_VERSION = persistObject.getPreference('currentVersion');

	if (persistObject.SALRversion != persistObject.getPreference('currentVersion')) {
		persistObject = null;
		throw "XPCOM/Overlay version mismatch. Your Firefox profile is probably corrupt. Google for \"firefox profile support\" for help in setting up a new, clean profile.";
	}
	if (!persistObject._syncTransferObject) {
		persistObject.SetSyncTransferObject(new SALR_FTPTransferObject());
	}
	var isWindows = (navigator.platform.indexOf("Win")!=-1);
	persistObject.ProfileInit(isWindows);
	if (persistObject._starterr) {
		alert( "SALR Startup Error:\n\n"+persistObject._starterr );
	}
	setInterval(SALR_TimerTick, 1000);
	setInterval(function(){SALR_SyncTick(false,false);}, 60*1000);
	setTimeout(function(){SALR_SyncTick(false,false);}, 10);
	persistObject._PNGCreator = new PNGMaker();
	if (persistObject._killChecked == false) {
		saLastReadKillCheck();
	}
	//if (persistObject._killed!=true) {
	//      if ( persistObject && persistObject.TimeManager == null ) {
	//         var tm = new SALastRead_TimeManager();
	//         persistObject.TimeManager = tm;
	//      }
	if ( persistObject && persistObject.LastRunVersion != SALR_CURRENT_VERSION ) {
		needToShowChangeLog = true;
		upgradeFromVersion = persistObject.LastRunVersion;
		persistObject.LastRunVersion = SALR_CURRENT_VERSION;
	}
	if ( typeof(persistObject.xmlDoc) != "undefined" ) {
		window.addEventListener('load', salastread_windowOnLoad, true);
		window.addEventListener('beforeunload', salastread_windowOnBeforeUnload, true);
		window.addEventListener('unload', salastread_windowOnUnload, true);
	} else {
		alert("persistObject._starterr =\n" + persistObject._starterr);
	}
	//}
}
catch (e)
{
	alert("SALastRead init error: "+e);
	if(persistObject)
	alert("persistObject._starterr =\n" + persistObject._starterr);
}

/*
setTimeout(attachUpdater, 1);

function attachUpdater() {
document.getElementById("content").addEventListener("select", SALR_ContentUpdateCurrentBrowser, true);
}
*/
